diff --git a/ps3/ps02q/fsm_training_traffic.vhd b/ps3/ps02q/fsm_training_traffic.vhd new file mode 100644 index 0000000..0bb7fa8 --- /dev/null +++ b/ps3/ps02q/fsm_training_traffic.vhd @@ -0,0 +1,110 @@ +----------------------------- +-- Author +-- Date +-- Project name +-- Module name +-- +-- Detailed module description +-- +-- +-- Revision: +-- A - initial design +-- B - +-- +----------------------------- +library ieee; --always use this library +use ieee.std_logic_1164.all; --always use this library + +use ieee.numeric_std.all; --use this library if arithmetic required + + +--define connections to outside +entity fsm_training_traffic is +port +( + clk : in std_logic; + rst : in std_Logic; + light : out std_logic_vector(1 downto 0) +); +end fsm_training_traffic; + +--define inside of the module +architecture behavioral of fsm_training_traffic is + + --define inside use signals + signal state : std_logic_vector(1 downto 0) := "00"; --2b state + signal cnt : unsigned(7 downto 0) := x"00"; --8b counter + + --define components to use + + + +begin + --define the operation of the module! + + process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + state <= "00"; + cnt <= x"00"; + else + case state is + when "00" => --red light 30 secs + if cnt < 30 then + cnt <= cnt + 1; + state <= "00"; + else + cnt <= 0; + state <= "01"; + end if; + + when "01" => --yellow light 5 secs + if cnt < 5 then + cnt <= cnt + 1; + state <= "01"; + else + cnt <= 0; + state <= "10"; + end if; + + when "10" => --green light 30 secs + if cnt < 30 then + cnt <= cnt + 1; + state <= "10"; + else + cnt <= 0; + state <= "11"; + end if; + + when "11" => --yellow light 5 secs + if cnt < 5 then + cnt <= cnt + 1; + state <= "11"; + else + cnt <= 0; + state <= "00"; + end if; + + when others => + cnt <= 0; + state <= "00"; + + end case; + end if; + end if; + end process; + + + light <= "00"; + + + + + +end behavioral; + + + + + diff --git a/ps3/ps02q/tlc_tb.v b/ps3/ps02q/tlc_tb.v new file mode 100644 index 0000000..d8c5833 --- /dev/null +++ b/ps3/ps02q/tlc_tb.v @@ -0,0 +1,104 @@ +///////////////////////////////////////////////////////////////// +// Author - Imants Pulkstenis +// Date - 23.02.2020 +// Project name - PS03 +// Module name - Testbench for Smart traffic light controler +// +// Detailed module description: +// +// Generating the stimulation +// Clk - Generate the 1GHz clock input +// Rst - generate both high and low reset to ensure correct start up, per Required functionality +// MR_cars - generate multiple values to simulate real world traffic situation (e.g. at night some +// cars arrive once per 60nanoseconds, in day – more cars) and verify that smart traffic light controller is working correctly. +// +// The test can be executed using Icarus Verilog! +// The result can be evaluated in GTKwave application. +// Code: +// iverilog -o output.vvp tlc_tb.v && vvp output.vvp +// gtkwave -f wave.vcd +// +// Revision: +// A - initial design +// B - +// C - +// +/////////////////////////////////////////////////////////////////// + +//UUT module +`include "traffic_light_controler.v" + +// 1GHz clock -> 1ns period +// 50% duty cycle 0.5ns HIGH and 0.5ns LOW +// `timescale [time unit] / [time precision] +`timescale 1ns / 100ps + +//define module +module tlc_tb (); + +//define inside use signals +reg clk = 1'b0; +reg rst = 1'b1; +reg [7:0] MR_cars = 'b0; + +integer ii=0; + +//---------Test script---------------- +// 50% duty cycle clock +always #0.5 clk <= ~clk; + +//-----Unit Under test--------------- +smart_tl_ctl #( + .PARAMETER(45) +) unit_under_test ( + .clk(clk), + .rst(rst), + .MR_cars(MR_cars), + .MR_ctl(), + .SR_ctl()); + +//---------Reset Test-------------------- +initial begin + rst = 0; + #10; + rst = 1; + #200 + rst = 0; + #100; + rst = 1; + +end + + +initial + begin + //---------Daytime traffic Test-------------------- + for (ii=0; ii<50; ii=ii+1) + begin + MR_cars = ii; + #10; + end + MR_cars = 0; + #100; + //---------Nighttime traffic Test-------------------- + for (ii=0; ii<50; ii=ii+1) + begin + MR_cars = ii; + #60; + end + #100; + $finish(); + end + +// just print text +initial begin + $display(" "); + $display("----------------------------------------------"); + $display(" Starting Testbench..."); + $dumpfile("wave.vcd"); + $dumpvars(0); + $display("----------------------------------------------"); + $display(" "); +end + +endmodule \ No newline at end of file diff --git a/ps3/ps02q/traffic_light_controler.v b/ps3/ps02q/traffic_light_controler.v index 54a3088..42f2eaa 100644 --- a/ps3/ps02q/traffic_light_controler.v +++ b/ps3/ps02q/traffic_light_controler.v @@ -48,9 +48,9 @@ module smart_tl_ctl #( parameter PARAMETER = 45, - MR_GREEN_TIME = 30, - SR_GREEN_TIME = 10, - YELLOW_TIME = 3 + MR_GREEN_TIME = 30-1, + SR_GREEN_TIME = 10-1, + YELLOW_TIME = 3-1 )( input clk, input rst, @@ -60,110 +60,115 @@ module smart_tl_ctl #( parameter //-------------Internal Constants--------------------------- localparam [2:0] IDLE = 'h0, - MR_GREEN_1 = 'h1, - MR_GREEN_2 = 'h2, + MR_GREEN_A = 'h1, + MR_GREEN_B = 'h2, MR_YELLOW = 'h3, SR_GREEN = 'h4, - MR_YELLOW = 'h5; + SR_YELLOW = 'h5; //-------------Internal signals and components-------------- reg [2:0] r_state = IDLE, - r_next = IDLE; + r_next = MR_GREEN_A; reg [4:0] r_cnt = 'b0; -reg [1:0] MR_ctl = 'b0, - SR_ctl = 'b0; +reg [1:0] r_MR_ctl = 'b0, + r_SR_ctl = 'b0; //------------ assignning combionational logic-------------- assign MR_ctl = r_MR_ctl; assign SR_ctl = r_SR_ctl; -//---------state register sequential always block----------- -always @(posedge clk ) begin - if (rst) - r_state <= r_next; - else - r_state <= IDLE; -end //----next state & outputs, combinational always block------ always@(posedge clk) begin + if (rst) begin case(r_state) IDLE: begin - r_MR_ctl = 'b00; - r_SR_ctl = 'b00; - r_next = MR_GREEN_1; - r_cnt = 'd0; + r_MR_ctl <= 'b00; + r_SR_ctl <= 'b00; + r_state <= MR_GREEN_A; + r_cnt <= 'd0; end - MR_GREEN_1: begin - r_MR_ctl = 'b11; - r_SR_ctl = 'b00; - if (r_cnt < MR_GREEN_TIME) begin - r_cnt = r_cnt + 1; - r_next = MR_GREEN_1; + MR_GREEN_A: begin + r_MR_ctl <= 'b11; + r_SR_ctl <= 'b01; + if (r_cnt >= MR_GREEN_TIME) begin + if (MR_cars == 0) begin + r_cnt <= 0; + r_state <= MR_GREEN_A; + end + else if (MR_cars < PARAMETER) begin + r_cnt <= 0; + r_state <= MR_GREEN_B; + end + else if (MR_cars >= PARAMETER) begin + r_cnt <= 0; + r_state <= MR_YELLOW; + end end - else if (r_cnt >= MR_GREEN_TIME) & (MR_cars == 0) begin - r_cnt = 0; - r_next = MR_GREEN_1; - end - else if (r_cnt >= MR_GREEN_TIME) & (MR_cars < PARAMETER) begin - r_cnt = 0; - r_next = MR_GREEN_2; - end - else if (r_cnt >= MR_GREEN_TIME) & (MR_cars >= PARAMETER) begin - r_cnt = 0; - r_next = MR_YELLOW; + else begin + r_state <= MR_GREEN_A; + r_cnt <= r_cnt + 1; end end - MR_GREEN_2: begin - r_MR_ctl = 'b11; - r_SR_ctl = 'b00; - if (r_cnt < MR_GREEN_TIME) begin - r_cnt = r_cnt + 1; - r_next = MR_GREEN_2; + MR_GREEN_B: begin + r_MR_ctl <= 'b11; + r_SR_ctl <= 'b01; + if (r_cnt >= MR_GREEN_TIME) begin + r_cnt <= 0; + r_state <= MR_YELLOW; end - else if (r_cnt >= MR_GREEN_TIME) begin - r_cnt = 0; - r_next = MR_YELLOW; + else begin + r_cnt <= r_cnt + 1; + r_state <= MR_GREEN_B; end end MR_YELLOW: begin - r_MR_ctl = 'b10; - r_SR_ctl = 'b10; - if (r_cnt < YELLOW_TIME) begin - r_cnt = r_cnt + 1; - r_next = MR_YELLOW; + r_MR_ctl <= 'b10; + r_SR_ctl <= 'b10; + if (r_cnt >= YELLOW_TIME) begin + r_cnt <= 0; + r_state <= SR_GREEN; end - else if (r_cnt >= YELLOW_TIME) begin - r_cnt = 0; - r_next = SR_GREEN; + else begin + r_cnt <= r_cnt + 1; + r_state <= MR_YELLOW; + end end SR_GREEN: begin - r_MR_ctl = 'b00; - r_SR_ctl = 'b11; - if (r_cnt < SR_GREEN_TIME) begin - r_cnt = r_cnt + 1; - r_next = SR_GREEN; + r_MR_ctl <= 'b01; + r_SR_ctl <= 'b11; + if (r_cnt >= SR_GREEN_TIME) begin + r_cnt <= 0; + r_state <= SR_YELLOW; end - else if (r_cnt >= SR_GREEN_TIME) begin - r_cnt = 0; - r_next = MR_YELLOW; + else begin + r_cnt <= r_cnt + 1; + r_state <= SR_GREEN; end end - MR_YELLOW: begin - r_MR_ctl = 'b10; - r_SR_ctl = 'b10; - if (r_cnt < YELLOW_TIME) begin - r_cnt = r_cnt + 1; - r_next = MR_YELLOW; - end - else if (r_cnt >= YELLOW_TIME) begin + SR_YELLOW: begin + r_MR_ctl <= 'b10; + r_SR_ctl <= 'b10; + if (r_cnt >= YELLOW_TIME) begin r_cnt = 0; - r_next = MR_GREEN_1; + r_state <= MR_GREEN_A; + end + else begin + r_cnt <= r_cnt + 1; + r_state <= SR_YELLOW; end end - default: r_next <= IDLE; // on error + default: r_state <= IDLE; // on error endcase + end + else begin + r_state <= IDLE; + + r_MR_ctl <= 'b00; + r_SR_ctl <= 'b00; + r_cnt <= 0; + end end diff --git a/ps3/ps02q/traffic_light_controler.vhdl b/ps3/ps02q/traffic_light_controler.vhdl new file mode 100644 index 0000000..3566274 --- /dev/null +++ b/ps3/ps02q/traffic_light_controler.vhdl @@ -0,0 +1,128 @@ +---------------------------------------------------------------- +-- Author - Imants Pulkstenis +-- Date - 23.02.2020 +-- Project name - PS03 +-- Module name - Smart traffic light controler +-- +-- Detailed module description: +-- +-- Task is to develop a Smart Traffic Light Controller VHDL +-- module using finite state machine principle (FSM). +-- +-- Port description +-- | Port name  | Direction  | Description  | +-- |------------|------------|--------------------------------------------------------------------------------------------------------------------------| +-- | Clk  | In  | 1 GHz clock (1 ns period)  | +-- | Rst  | In  | Active low reset  | +-- | MR_cars  | In  | An 8-bit input signal indicating the number of waiting cars at the secondary road traffic light. Interpret as unsigned.  | +-- | MR_ctl  | Out  | Main road traffic light controlling signal  | +-- | SR_ctl  | Out  | Secondary road traffic light controlling signal | + +-- Output light mapping for MR_ctl and SR_ctl signals to be used +-- | Value (2bit binary)  | Light output  | +-- |----------------------|-----------------------------------| +-- | 00  | No light – traffic light is dark  | +-- | 01  | Red light  | +-- | 10  | Yellow light  | +-- | 11  | Green light | +-- +-- When rst is low, outputs should be dark, no light visible +-- When rst is high then: +-- Minimum main road green period length should be at least 30 nanoseconds. When green period ends: +-- If there are zero cars waiting on the secondary road, then main road starts the green state again +-- If there are less than PARAMETER cars waiting on the secondary road, green period length is extended +-- by 30 nanoseconds and then switches to red (and secondary to green) +-- If there are equals/more than PARAMETER cars waiting on the secondary road, main road switches to red (and secondary to green) +-- Secondary road green period length is 10 nanoseconds, after that, main road switches to green (and secondary to red) +-- Each transition (red to green and green to red) should go through 3 nanoseconds yellow light. Yellow lights can happen at the same +-- time in both traffic directions. +-- MR_ctl and SR_ctl both must not be green at the same time to avoid traffic accidents. +-- PARAMETER = 45. +-- +-- Revision: +-- A - initial design +-- B - +-- C - +-- +------------------------------------------------------------------ + +-- define libraries to be used [part 2 of the VHDL file] +library ieee; --always use this library +use ieee.std_logic_1164.all; --always use this library +use ieee.numeric_std.all; --use this library if arithmetic required + +--Entity declaration [part 3 of the VHDL file]. +entity smart_tl_ctl is + generic + ( + PARAMETER : integer := 45 + ); + port + ( + clk : in std_logic; + rst : in std_Logic; + MR_cars : in std_logic_vector(7 downto 0); + MR_ctl : out std_logic_vector(2 downto 0); + SR_ctl : out std_logic_vector(2 downto 0) + ); + end smart_tl_ctl; + +--define inside of the module +architecture behavioral of alu is + --define inside use signals and components [part 4 of the VHDL file] + signal state : std_logic_vector(2 downto 0) := "000"; --2b state + signal cnt : std_logic_vector(7 downto 0) := x"00"; --8b counter + + +begin + --define the operation of the module! [part 5 of the VHDL file] + +process(clk) +begin + if rising_edge(clk) then + if rst = '1' then + state <= "000"; + cnt <= x"00"; + else + case state is + when "000" => -- lights off secs + state <= "001"; + cnt <= 0; + state <= "001"; + when "001" => -- MR green light 30 secs + if cnt < 5 then + cnt <= cnt + 1; + state <= "001"; + else + cnt <= 0; + state <= "010"; + end if; + + when "010" => -- MR green light 30 secs + if cnt < 30 then + cnt <= cnt + 1; + state <= "10"; + else + cnt <= 0; + state <= "11"; + end if; + + when "11" => --yellow light 5 secs + if cnt < 5 then + cnt <= cnt + 1; + state <= "11"; + else + cnt <= 0; + state <= "00"; + end if; + + when others => + cnt <= 0; + state <= "00"; + + end case; + end if; + end if; +end process; + +end behavioral; \ No newline at end of file