traffic light state machine verilog

This article is a summary of the state machine-traffic light part of the article Verilog learning code summary .

This state machine is a mealy type sequential circuit.
Adopt three-stage design.

topic

Design a traffic light controller. At an intersection, the east-west direction is the main road (HighWay), and the north-south direction is the secondary road (CountryWay). There are very few vehicles on the secondary arterial road, so there is a vehicle detector (Sensor) at the intersection to determine whether there are cars on the secondary arterial road. If there are no cars, the main road will always have a green light; if there are cars on the secondary road, the main road will have a red light (Red) after 40 seconds of passage on the main road, while the secondary road will have a green light, and the passage time will be 20 seconds. At this time, regardless of whether there are cars on the sub-trunk road, the sub-trunk road will have a red light, while the main road will have a green light. There is a 4-second yellow light in the transition from green light to red light.

Require:

1. Draw a finite state machine and indicate the state transition conditions;

2. Write program code, mark instructions and explanations;

3. Write a verification program to fully verify the design.


State transition diagram

Insert image description here

source code

The program source code is divided into 2 sub-modules (counter module + traffic light module) + top module

Counter module
module counter(out,clk,enable,rst);
output[6:0]  out;
input clk, rst,enable;
reg[6:0] out;
    
always @ (posedge rst or posedge clk) begin
  if (rst) begin
    out <= 8'b0;
    end else if (enable) begin
    out <= (out + 1)%69;
  end
end

endmodule
traffic light module
module light(highWay,countryWay,counter_enable,clk,rst,senor,count);
input clk,rst,senor;
input [6:0] count;
output counter_enable;
output [1:0] highWay,countryWay;
reg counter_enable;
reg [1:0] highWay,countryWay;
//标志计数状态
wire [6:0] count;

//主干状态,副干状态与之对应
reg [1:0] cur_state,next_state;
//灯输出结果常量
parameter GREEN = 2'b00,
          YELLOW = 2'b01,
          RED = 2'b11;
//状态常量
parameter PASS = 2'b00,
          WAIT1 = 2'b01,
          WAIT2 = 2'b10,
          STOP = 2'b11;          

//根据下一状态或重置改变现在状态
always @(posedge rst or posedge clk) begin
  if(rst) begin
    cur_state <= PASS;
    next_state <= PASS;
    counter_enable <= 0;
  end else begin
    cur_state <= next_state;
  end
end

//不同状态不同输出
always @(cur_state) begin
  case (cur_state)
    PASS:begin
      highWay = GREEN;
      countryWay = RED;
    end 
    WAIT1:begin
      highWay = YELLOW;
      countryWay = YELLOW;
    end
    WAIT2:begin
      highWay = YELLOW;
      countryWay = YELLOW;
    end
    STOP:begin
      highWay = RED;
      countryWay = GREEN;
    end
    default: begin
      highWay = GREEN;
      countryWay = RED;
    end 
  endcase
end

//根据输入改变下一预设状态
always @(senor or count) begin
  next_state = PASS;
  case (cur_state)
    PASS:begin
      if (senor) begin
        if (count==40) begin
          next_state = WAIT1;
        end
        counter_enable = 1;
      end else begin
        counter_enable = 0;
      end
    end
    WAIT1:begin
      next_state = (count==44)?STOP:WAIT1;
    end
    WAIT2:begin
      next_state = (count==68)?PASS:WAIT2;
    end
    STOP:begin
      next_state = (count==64)?WAIT2:STOP;
    end
  endcase
end

endmodule
top-level module
module top(highWay,countryWay,clk,rst,senor);
input clk,rst,senor;
output [1:0] highWay,countryWay;
wire counter_enable;
wire [6:0] count;

light i1(.highWay(highWay),.countryWay(countryWay),
  .counter_enable(counter_enable),
  .clk(clk),.rst(rst),
  .senor(senor),.count(count));

counter c1(.out(count),.clk(clk),
  .enable(counter_enable),.rst(rst));

endmodule 

Note: In the current code, the trunk and deputy trunk states correspond to each other by default, red (main)-green (deputy), yellow (main)-yellow (deputy), green (main)-red (deputy).

But that's not the case.

When designing many traffic lights, a yellow light only needs to be interspersed when red->green, just like the last sentence of the question. Therefore, my design actually does not meet the requirements of the question.

If you want to make it more realistic, then you need to add two more variables: cur_state2and next_state2to save the status of the deputy leader. At the same time, delete the state in the state machine WAIT1so that it PASSpoints directly STOP.

test code

`timescale 1ns/1ns
module tb_light;
reg clk,rst,senor;
wire [1:0] highWay,countryWay;
parameter INTERVAL = 10;

//初始化各值
initial begin
    clk = 1'b0;
    rst = 1'b0;
    senor = 1'b0;
end

//设定时钟周期
initial 
  forever #(INTERVAL/2) clk = ~clk;

//重置模块
initial begin
  #INTERVAL rst = 1;
  #INTERVAL rst = 0;
end

initial begin
  //测试副干有车情况
  #(5*INTERVAL) senor = 1'b1;
  //测试副干无车情况
  #(60*INTERVAL) senor = 1'b0;
  #(100*INTERVAL) $finish;
end

//实例化模块
top t1(highWay,countryWay,clk,rst,senor);

endmodule 

Note: The traffic light module is senorused to determine whether it is in the timing state. If in the test code, the time senor=0is in PASSthe state of the main trunk ( senor=0meaning that the deputy trunk car is gone, in the trunk PASSstate, the original car of the assistant trunk suddenly disappears? It may be too late to turn around at the intersection... so it is a false proposition in itself ——Of course, this excludes equipment failure). Note that the traffic light module does not clear the counter module, so the next time it is used, the senor=1trunk traffic time may be less than 40S.

Simulation

Insert image description here

Guess you like

Origin blog.csdn.net/qq_44856695/article/details/106142831