【FPGA】Verilog實現交通信號燈


更新:

其余各部分代碼已公布。

-------------------------------------------------------------------------------------------------------

大二數字電路的課程設計中,有一份日常作業使用Xilinx FPGA實現簡易交通信號燈,但很可惜當時時間有限,沒能最終完成。正好在這一學期選修SOPC設計課程,同樣采用了Xilinx FPGA,故打算重新完成交通信號燈的相關內容。

本項目采用Digilent公司生產的BASYS3開發板,基於Xilinx FPGA,該板子目前可以在馬雲家買到,不過價格偏貴,在校學生可在digilent官網申請以更低價格買入。

大致的框架如下,只是個構思,還很不完善,后續會進行修改。比如現在我目前並沒有把計時功能完全從State模塊中摘出來,只是用Timer實例化了一個1s計時器在里面,並且用count計數。

 

TOP代碼

module BASYS_BIGPROJECT_Top
(
input clk,
output wire[5:0]Trans_light,
output wire[3:0]Num_choose,
output wire[7:0]Num_data
);

wire [1:0]state_connect;
wire [2:0]count_connect;
//wire [6:0]Num_data_connect;
BASYS_BIGPROJECT_State state(
    .clk(clk),
    .state(state_connect),
    .count(count_connect)
    );

BASYS_BIGPROJECT_Display display(
    .clk(clk),
    .count(count_connect),
    .state(state_connect),
    .Trans_light(Trans_light),
    .Num_choose(Num_choose),
    .Num_data(Num_data)
    );

endmodule

 

State代碼

module BASYS_BIGPROJECT_State(
input clk,
output [1:0]state,
output [2:0]count
    );

reg [1:0]reg_state = 0;
reg [2:0]reg_count = 0;
wire cnt_connect;

Freq_divider clk_1s(
    .clk(clk),
    .rst(0),
    .count(cnt_connect)
    );

//states for lights
parameter MR_BG = 2'b00;
parameter MR_BY = 2'b01;
parameter MG_BR = 2'b11;
parameter MY_BR = 2'b10;

//green led for 4s, yellow led for 2s
always@(posedge cnt_connect)
begin
    case(reg_state)
    MR_BG:begin //main red, branch green
        if(reg_count<4) begin
            reg_state <= MR_BG;
            reg_count <= reg_count + 1;
        end
        else begin
            reg_state <= MR_BY;
            reg_count <= 3'b000;
        end
    end
    MR_BY:begin //main red, branch yellow
        if(reg_count<2) begin
            reg_state <= MR_BY;
            reg_count <= reg_count + 1;
        end
        else begin
            reg_state <= MG_BR;
            reg_count <= 3'b000;
        end
    end
    MG_BR:begin //main green, branch red
        if(reg_count<4) begin
            reg_state <= MG_BR;
            reg_count <= reg_count + 1;
        end
        else begin 
            reg_state <= MY_BR;
            reg_count <= 3'b000;
        end
    end
    MY_BR:begin //main yellow, branch red
        if(reg_count<2) begin
            reg_state <= MY_BR;
            reg_count <= reg_count + 1;
        end
        else begin
            reg_state <= MR_BG;
            reg_count <= 3'b000;
        end
    end
    endcase
end
assign state = reg_state;
assign count = reg_count;

endmodule

 

Display代碼

 

module BASYS_BIGPROJECT_Display
(
input clk,
input [1:0]state,
input [2:0]count,
output [5:0]Trans_light,
output [3:0]Num_choose,
output [7:0]Num_data
);

reg [5:0]reg_light = 0;
reg [3:0]reg_Num_digit = 0;
reg [3:0]reg_Num_choose = 4'b1110;
wire [7:0]Num_data_connect;
wire refresh;

reg [3:0]Data_Main = 0;
reg [3:0]Data_Branch = 0;
//divider for refresh
Freq_divider #(13)play(
    .clk(clk),
    .rst(1'b0),
    .count(refresh)
);
//Decode the digit
Digital_decode decoder(
    .clk(clk),
    .data(reg_Num_digit),
    .Trans_num(Num_data_connect)
    );

//switch the light
always @(posedge clk)
begin
    case(state)
        2'b00:begin
            reg_light <= 6'b100001;
            Data_Main <= 6 - count;
            Data_Branch <= 4 - count;
        end
        2'b01:begin
            reg_light <= 6'b100010;
            Data_Main <= 2 - count;
            Data_Branch <= 2 - count;
        end
        2'b11:begin
            reg_light <= 6'b001100;
            Data_Main <= 4 - count;
            Data_Branch <= 6 - count;
        end
        2'b10:begin
            reg_light <= 6'b010100;
            Data_Main <= 2 - count;
            Data_Branch <= 2 - count;
        end
    endcase
end

//Scanned display for digit
always @(posedge refresh)
begin
    if(reg_Num_choose == 4'b1110)
    begin
        reg_Num_choose <= 4'b1011;
        reg_Num_digit <= Data_Main;
    end
    else
    begin
        reg_Num_choose <= 4'b1110;
        reg_Num_digit <= Data_Branch;
    end
end

assign Trans_light = reg_light;
assign Num_choose = reg_Num_choose;
assign Num_data = Num_data_connect;
endmodule

 

Tools代碼

 

module Freq_divider
#(parameter N = 27)
(
input clk,
input rst,
output [N-1:0]freq_div,
output count
);
reg [N-1:0]regN = 0;
always@(posedge clk)
begin
    if(rst)
        regN <= 0;
    else
        regN <= regN+1;
end
assign freq_div = regN;
assign count = (regN == 2**N-1)?1'b1:1'b0;
endmodule

module Digital_decode
(
input clk,
input [3:0]data,
output [7:0]Trans_num
);

reg [7:0]reg_Trans_num = 0;

always@(posedge clk)
begin
   case(data)
       4'd0: reg_Trans_num <= 8'b0000_0011;
       4'd1: reg_Trans_num <= 8'b1001_1111;
       4'd2: reg_Trans_num <= 8'b0010_0101;
       4'd3: reg_Trans_num <= 8'b0000_1101;
       4'd4: reg_Trans_num <= 8'b1001_1001;
       4'd5: reg_Trans_num <= 8'b0100_1001;
       4'd6: reg_Trans_num <= 8'b0100_0001;
       4'd7: reg_Trans_num <= 8'b0001_1111;
       4'd8: reg_Trans_num <= 8'b0000_0001;
       4'd9: reg_Trans_num <= 8'b0000_1001;
       default: reg_Trans_num <= 8'b0001_0001;
   endcase
end
assign Trans_num = reg_Trans_num;
endmodule


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM