diff --git a/LAB1/sim/tb_KittCarPWM.vhd b/LAB1/sim/tb_KittCarPWM.vhd
new file mode 100644
index 0000000..c089ee6
--- /dev/null
+++ b/LAB1/sim/tb_KittCarPWM.vhd
@@ -0,0 +1,85 @@
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+
+ENTITY tb_KittCarPWM IS
+END tb_KittCarPWM;
+
+ARCHITECTURE testbench OF tb_KittCarPWM IS
+ -- Test constants
+ CONSTANT CLK_PERIOD : TIME := 10 ns;
+ CONSTANT RESET_TIME : TIME := 10*CLK_PERIOD;
+ CONSTANT TEST_DURATION : TIME := 10000 ms;
+
+ CONSTANT PERIOD : TIME := 10ms;
+
+ -- Signals
+ SIGNAL clk : STD_LOGIC := '0';
+ SIGNAL reset : STD_LOGIC := '0';
+ SIGNAL sw : STD_LOGIC_VECTOR(15 DOWNTO 0) := (OTHERS => '0');
+ SIGNAL led : STD_LOGIC_VECTOR(15 DOWNTO 0);
+
+ -- Device Under Test (DUT) instance
+ COMPONENT KittCarPWM
+ GENERIC (
+ CLK_PERIOD_NS : POSITIVE := 10;
+ MIN_KITT_CAR_STEP_MS : POSITIVE := 1;
+ NUM_OF_SWS : INTEGER := 16;
+ NUM_OF_LEDS : INTEGER := 16;
+ TAIL_LENGTH : INTEGER := 4
+ );
+ PORT (
+ reset : IN STD_LOGIC;
+ clk : IN STD_LOGIC;
+ sw : IN STD_LOGIC_VECTOR(NUM_OF_SWS - 1 DOWNTO 0);
+ led : OUT STD_LOGIC_VECTOR(NUM_OF_LEDS - 1 DOWNTO 0)
+ );
+ END COMPONENT;
+
+BEGIN
+ -- Connect DUT
+ dut_KittCarPWM : KittCarPWM
+ GENERIC MAP (
+ CLK_PERIOD_NS => 10,
+ MIN_KITT_CAR_STEP_MS => 1,
+ NUM_OF_SWS => 16,
+ NUM_OF_LEDS => 16,
+ TAIL_LENGTH => 4
+ )
+ PORT MAP (
+ reset => reset,
+ clk => clk,
+ sw => sw,
+ led => led
+ );
+
+ -- Clock generation process
+ clk <= not clk after CLK_PERIOD/2;
+
+ -- Reset Process
+ reset_wave :process
+ begin
+ reset <= '1';
+ wait for RESET_TIME;
+
+ reset <= not reset;
+ wait;
+ end process;
+
+ -- Test process
+ stim_proc : PROCESS
+ BEGIN
+ -- wait for reset
+ sw <= "0000000000000000";
+ WAIT FOR RESET_TIME;
+
+ -- Start
+ for I in 0 to 2**16-1 loop
+ sw <= std_logic_vector(to_unsigned(I, 16));
+ WAIT FOR PERIOD;
+ end loop;
+
+ -- End simulation
+ WAIT;
+ END PROCESS;
+END testbench;
diff --git a/LAB1/src/KittCar.vhd b/LAB1/src/KittCar.vhd
index 8da3ccd..662caeb 100644
--- a/LAB1/src/KittCar.vhd
+++ b/LAB1/src/KittCar.vhd
@@ -33,27 +33,30 @@ ARCHITECTURE Behavioral OF KittCar IS
CONSTANT MIN_KITT_CAR_STEP_NS : UNSIGNED(46 DOWNTO 0) := to_unsigned(MIN_KITT_CAR_STEP_MS * 1000000, 47);
SIGNAL leds_sr : STD_LOGIC_VECTOR(led'RANGE) := (OTHERS => '0');
- SIGNAL n_period : UNSIGNED(NUM_OF_SWS DOWNTO 0) := to_unsigned(1, NUM_OF_SWS + 1);
- SIGNAL up : STD_LOGIC := '1';
BEGIN
-- Sincronous logic
PROCESS (clk, reset)
VARIABLE counter : UNSIGNED(46 DOWNTO 0) := (OTHERS => '0');
+ VARIABLE n_period : UNSIGNED(NUM_OF_SWS DOWNTO 0) := to_unsigned(1, NUM_OF_SWS + 1);
+ VARIABLE up : STD_LOGIC := '1';
BEGIN
IF reset = '1' THEN
leds_sr <= (OTHERS => '0');
counter := (OTHERS => '0');
ELSIF rising_edge(clk) THEN
+ -- Handle the switch
+ n_period := unsigned('0' & sw) + 1;
+
-- Kitt logic
IF unsigned(leds_sr) = 0 THEN
leds_sr(0) <= '1';
- up <= '1';
+ up := '1';
ELSIF leds_sr(led'HIGH) = '1' THEN
- up <= '0';
+ up := '0';
ELSIF leds_sr(led'LOW) = '1' THEN
- up <= '1';
+ up := '1';
END IF;
-- Increment the counter
@@ -75,12 +78,6 @@ BEGIN
END IF;
END PROCESS;
- -- Handle the switch
- PROCESS (sw)
- BEGIN
- n_period <= unsigned('0' & sw) + 1;
- END PROCESS;
-
led <= leds_sr;
END Behavioral;
\ No newline at end of file
diff --git a/LAB1/src/KittCarPWM.vhd b/LAB1/src/KittCarPWM.vhd
index f2d29a0..62d05e6 100644
--- a/LAB1/src/KittCarPWM.vhd
+++ b/LAB1/src/KittCarPWM.vhd
@@ -32,10 +32,7 @@ END KittCarPWM;
ARCHITECTURE Behavioral OF KittCarPWM IS
COMPONENT PulseWidthModulator
GENERIC (
- BIT_LENGTH : INTEGER RANGE 1 TO 16;
- T_ON_INIT : POSITIVE;
- PERIOD_INIT : POSITIVE;
- PWM_INIT : STD_LOGIC
+ BIT_LENGTH : INTEGER
);
PORT (
reset : IN STD_LOGIC;
@@ -47,88 +44,79 @@ ARCHITECTURE Behavioral OF KittCarPWM IS
);
END COMPONENT;
- TYPE led_reg IS ARRAY (TAIL_LENGTH - 1 DOWNTO 0) OF INTEGER RANGE 0 TO led'HIGH;
-
+ TYPE leds_sr_type IS ARRAY (TAIL_LENGTH - 1 DOWNTO 0) OF INTEGER RANGE led'LOW TO led'HIGH;
+
CONSTANT MIN_KITT_CAR_STEP_NS : UNSIGNED(46 DOWNTO 0) := to_unsigned(MIN_KITT_CAR_STEP_MS * 1000000, 47);
- CONSTANT BIT_LENGTH : INTEGER RANGE 1 TO 16 := 8;
+ CONSTANT BIT_LENGTH : INTEGER := 5;
+
+ SIGNAL pwms : STD_LOGIC_VECTOR(TAIL_LENGTH - 1 DOWNTO 0) := (OTHERS => '0');
+ SIGNAL leds_sig : STD_LOGIC_VECTOR(NUM_OF_LEDS - 1 DOWNTO 0) := (OTHERS => '0');
- SIGNAL leds_sr : led_reg := (OTHERS => 0);
- SIGNAL leds_pwm : STD_LOGIC_VECTOR(TAIL_LENGTH - 1 DOWNTO 0) := (OTHERS => '0');
- SIGNAL led_sig : STD_LOGIC_VECTOR(NUM_OF_LEDS - 1 DOWNTO 0) := (OTHERS => '0');
- SIGNAL n_period : UNSIGNED(NUM_OF_SWS DOWNTO 0) := to_unsigned(1, NUM_OF_SWS + 1);
- SIGNAL up : STD_LOGIC := '1';
BEGIN
- -- Instantiate the PWM
+ -- Instantiate the PWM modules
PWM : FOR i IN 1 TO TAIL_LENGTH GENERATE
BEGIN
PWM : PulseWidthModulator
GENERIC MAP(
- BIT_LENGTH => BIT_LENGTH,
- T_ON_INIT => 64,
- PERIOD_INIT => 128,
- PWM_INIT => '0'
+ BIT_LENGTH => BIT_LENGTH
)
PORT MAP(
reset => reset,
clk => clk,
Ton => STD_LOGIC_VECTOR(to_unsigned(i, BIT_LENGTH)),
Period => STD_LOGIC_VECTOR(to_unsigned(TAIL_LENGTH - 1, BIT_LENGTH)),
- PWM => leds_pwm(i - 1)
+ PWM => pwms(i - 1)
);
END GENERATE;
- -- Sincronous logic
+ -- Synchronous logic for LED control
PROCESS (clk, reset)
- VARIABLE counter : UNSIGNED(46 DOWNTO 0) := (OTHERS => '0');
+ VARIABLE up : STD_LOGIC := '1'; -- Direction of LED movement
+ VARIABLE leds_sr : leds_sr_type := (OTHERS => 0); -- Shift register for LED positions
+ VARIABLE counter : UNSIGNED(46 DOWNTO 0) := (OTHERS => '0'); -- Timing counter
+ VARIABLE n_period : UNSIGNED(NUM_OF_SWS DOWNTO 0) := to_unsigned(1, NUM_OF_SWS + 1); -- Period multiplier
BEGIN
IF reset = '1' THEN
- leds_sr <= (OTHERS => 0);
- led_sig <= (OTHERS => '0');
- counter := (OTHERS => '0');
- up <= '1';
+ leds_sig <= (OTHERS => '0'); -- Turn off all LEDs
+ leds_sr := (OTHERS => 0); -- Reset shift register
+ counter := (OTHERS => '0'); -- Reset counter
+ up := '1'; -- Set initial direction
ELSIF rising_edge(clk) THEN
+ -- Update period multiplier based on switches
+ n_period := unsigned('0' & sw) + 1;
- -- Kitt logic: Update direction
- IF leds_sr(TAIL_LENGTH - 1) = led'high THEN
- up <= '0';
- ELSIF leds_sr(TAIL_LENGTH - 1) = led'low THEN
- up <= '1';
- END IF;
-
- -- Increment the counter
+ -- Increment counter
counter := counter + to_unsigned(CLK_PERIOD_NS, counter'LENGTH);
- -- Calculate the number of periods
+ -- Check if counter exceeds threshold
IF counter >= (MIN_KITT_CAR_STEP_NS * n_period) THEN
-
- -- Reset led_sig
- led_sig <= (OTHERS => '0');
-
- -- Shift the leds
- IF up = '1' THEN
- leds_sr <= (leds_sr(TAIL_LENGTH - 1) + 1) & leds_sr(TAIL_LENGTH - 1 DOWNTO 1);
- ELSE
- leds_sr <= (leds_sr(TAIL_LENGTH - 1) - 1) & leds_sr(TAIL_LENGTH - 1 DOWNTO 1);
+ -- Update direction
+ IF leds_sr(leds_sr'HIGH) = led'high THEN
+ up := '0'; -- Change to backward
+ ELSIF leds_sr(leds_sr'HIGH) = led'low THEN
+ up := '1'; -- Change to forward
END IF;
- -- Assign the LEDs
- FOR i IN 0 TO TAIL_LENGTH - 1 LOOP
- led_sig(leds_sr(i)) <= leds_pwm(i);
- END LOOP;
+ -- Shift LEDs based on direction
+ IF up = '1' THEN
+ leds_sr := (leds_sr(leds_sr'HIGH) + 1) & leds_sr(leds_sr'HIGH DOWNTO 1);
+ ELSE
+ leds_sr := (leds_sr(leds_sr'HIGH) - 1) & leds_sr(leds_sr'HIGH DOWNTO 1);
+ END IF;
- -- Reset the counter
- counter := (OTHERS => '0');
+ counter := (OTHERS => '0'); -- Reset counter
END IF;
+
+ -- Assign PWM signals to LEDs
+ leds_sig <= (OTHERS => '0');
+ FOR i IN leds_sr'REVERSE_RANGE LOOP
+ leds_sig(leds_sr(i)) <= pwms(i);
+ END LOOP;
END IF;
END PROCESS;
- -- Handle the switch
- PROCESS (sw)
- BEGIN
- n_period <= unsigned('0' & sw) + 1;
- END PROCESS;
-
- led <= led_sig;
+ -- Assign LED signals to output
+ led <= leds_sig;
END Behavioral;
\ No newline at end of file
diff --git a/LAB1/src/PulseWidthModulator.vhd b/LAB1/src/PulseWidthModulator.vhd
index bd7c9d5..674779d 100644
--- a/LAB1/src/PulseWidthModulator.vhd
+++ b/LAB1/src/PulseWidthModulator.vhd
@@ -33,10 +33,7 @@ use IEEE.NUMERIC_STD.ALL;
entity PulseWidthModulator is
Generic(
- BIT_LENGTH : INTEGER RANGE 1 to 16 := 8;
- T_ON_INIT : POSITIVE := 64;
- PERIOD_INIT : POSITIVE := 128;
- PWM_INIT : STD_LOGIC := '0'
+ BIT_LENGTH : INTEGER RANGE 1 to 16 := 8
);
Port (
reset : IN STD_LOGIC;
diff --git a/LAB1/vivado/lab1_kit_car_pwm/lab1_kit_car_pwm.xpr b/LAB1/vivado/lab1_kit_car_pwm/lab1_kit_car_pwm.xpr
index cff86d3..47c5e4d 100644
--- a/LAB1/vivado/lab1_kit_car_pwm/lab1_kit_car_pwm.xpr
+++ b/LAB1/vivado/lab1_kit_car_pwm/lab1_kit_car_pwm.xpr
@@ -46,7 +46,7 @@
-
+
@@ -107,9 +107,15 @@
+
+
+
+
+
+
-
+