Verilog 交通信号灯控制模块代码详解 - 实现多种模式
这是一个 Verilog 代码模块,用于控制交通信号灯的显示。下面是代码的详细解释:
-
'module control(...)': 定义了一个名为 'control' 的模块,其中包含了输入输出端口。
-
'input CLOCK_50': 板载的 50MHz 时钟信号。
-
'input Q_KEY': 按键输入。
-
'input guang1, guang2': 分别表示南北方向和东西方向的流量传感器接口。
-
'input [9:1] KEY': 按键输入。
-
'output reg[15:0] data': 输出到数码管的数据。
-
'output reg[15:0] liul': 输出流量计数器的数据。
-
'output reg[5:0] led': 输出到 LED 灯的数据。
-
'reg[7:0] nabeiliu, dongxiliu': 分别表示南北方向和东西方向的流量计数器。
-
'reg F1, F2': 用于检测时钟信号的状态。
-
'always @(posedge CLOCK_50 or negedge Q_KEY)': 当时钟信号上升沿或按键信号下降沿时,执行以下代码。
-
'if(!Q_KEY)': 如果按键信号为低电平(按键被按下),执行以下代码:
- 'F1<=1'b1; F2<=1'b1;': 将 'F1' 和 'F2' 赋值为 1,初始化状态。
-
'else': 如果按键信号为高电平(按键松开),执行以下代码:
-
'F1<=guang1;': 将 'F1' 赋值为 'guang1' 的值,即南北方向流量传感器的状态。
-
'F2<=F1;': 将 'F2' 赋值为 'F1' 的值,用于检测时钟信号的下降沿。
-
-
'assign SCK_fallingedge1 = F2 && !F1;': 检测时钟信号的下降沿,当 'F2' 为 1 且 'F1' 为 0 时,'SCK_fallingedge1' 为 1。
-
'assign SCK_risingedge1 = F1 && !F2;': 检测时钟信号的上升沿,当 'F1' 为 1 且 'F2' 为 0 时,'SCK_risingedge1' 为 1。
-
'reg F3, F4;': 用于检测东西方向流量传感器的状态。
-
'reg aa, bb;': 暂未使用的变量。
-
'always @(posedge CLOCK_50 or negedge Q_KEY)': 当时钟信号上升沿或按键信号下降沿时,执行以下代码。
-
'if(!Q_KEY)': 如果按键信号为低电平(按键被按下),执行以下代码:
- 'F3<=1'b1; F4<=1'b1;': 将 'F3' 和 'F4' 赋值为 1,初始化状态。
-
'else': 如果按键信号为高电平(按键松开),执行以下代码:
-
'F3<=guang2;': 将 'F3' 赋值为 'guang2' 的值,即东西方向流量传感器的状态。
-
'F4<=F3;': 将 'F4' 赋值为 'F3' 的值,用于检测时钟信号的下降沿。
-
-
'assign SCK_fallingedge2 = F4 && !F3;': 检测时钟信号的下降沿,当 'F4' 为 1 且 'F3' 为 0 时,'SCK_fallingedge2' 为 1。
-
'assign SCK_risingedge2 = F3 && !F4;': 检测时钟信号的上升沿,当 'F3' 为 1 且 'F4' 为 0 时,'SCK_risingedge2' 为 1。
-
'reg [25:0] cnt2, cnt1, cnt;': 定义三个计数器变量。
-
'reg uu1, uu2;': 用于记录南北方向和东西方向流量传感器的状态。
-
'reg [7:0] t_buf1, t_buf2;': 暂未使用的变量。
-
'reg [3:0] moshi;': 用于记录当前的模式。
-
'reg[2:0] state;': 用于记录交通信号灯的状态。
-
'reg [6:0] shijiandx, shijiannb;': 分别表示东西方向和南北方向的通行时间。
-
'reg ff;': 用于记录夜间模式的闪烁状态。
-
'reg [7:0] sec;': 用于记录当前秒数。
-
'reg [6:0] ttdx, ttnb;': 用于记录东西方向和南北方向的剩余时间。
-
'wire [9:1] key_val;': 用于记录按键的值。
-
'key_debounce u0(...)': 实例化一个按键消抖模块,并将按键值输出到 'key_val'。
-
'always @(posedge CLOCK_50, negedge Q_KEY)': 当时钟信号上升沿或按键信号下降沿时,执行以下代码。
-
'if (!Q_KEY)': 如果按键信号为低电平(按键被按下),执行以下代码:
-
'nabeiliu<=0; dongxiliu<=0;': 清零南北方向和东西方向的流量计数器。
-
'cnt1 <= 0; cnt <= 0;': 清零计数器。
-
'sec=0; moshi=0; shijiandx=20; shijiannb=20; cnt2=0;': 初始化秒数、模式、通行时间和计数器。
-
-
'else': 如果按键信号为高电平(按键松开),执行以下代码:
-
'case (1'b0)': 根据按键值执行不同的操作。
-
'key_val[1]': 调节南北方向通行时间,并将秒数清零。
-
'key_val[2]': 减少南北方向通行时间,并将秒数清零。
-
'key_val[3]': 调节东西方向通行时间,并将秒数清零。
-
'key_val[4]': 减少东西方向通行时间,并将秒数清零。
-
'key_val[5]': 设置东西方向通行,南北方向禁止通行,并将秒数清零。
-
'key_val[6]': 设置南北方向通行,东西方向禁止通行,并将秒数清零。
-
'key_val[7]': 设置夜间模式,并将秒数清零。
-
'key_val[8]': 设置按流量通行模式,并将秒数清零。
-
'key_val[9]': 设置默认模式,并将秒数清零。
-
-
'if(SCK_fallingedge1 == 1)': 如果检测到南北方向流量传感器的下降沿,将 'uu1' 赋值为 1。
-
'if(SCK_fallingedge2 == 1)': 如果检测到东西方向流量传感器的下降沿,将 'uu2' 赋值为 1。
-
'if (cnt1 == 9_999_999)': 如果 'cnt1' 计数器溢出,执行以下代码:
-
'cnt1 <= 0;': 将 'cnt1' 计数器清零。
-
'if(guang1==1&&uu1==1)': 如果南北方向流量传感器检测到车辆且 'uu1' 为 1,将 'uu1' 清零并增加南北方向的流量计数器。
-
'if(guang2==1&&uu2==1)': 如果东西方向流量传感器检测到车辆且 'uu2' 为 1,将 'uu2' 清零并增加东西方向的流量计数器。
-
-
'else': 如果 'cnt1' 计数器未溢出,则 'cnt1' 自增 1。
-
'if(moshi==0)': 如果处于默认模式,执行以下代码:
-
'if (cnt == 49_999_999)': 如果 'cnt' 计数器溢出,执行以下代码:
-
'cnt <= 0;': 将 'cnt' 计数器清零。
-
'if(sec==(shijiannb+shijiandx+11))sec=0; else sec=sec+1;': 计算秒数,如果秒数大于总通行时间,则清零秒数,否则自增 1。
-
'if(sec<=shijiannb)': 如果秒数小于南北方向的通行时间,执行以下代码:
-
'state=0;': 设置南北方向绿灯,东西方向红灯。
-
'ttnb=shijiannb-sec;': 计算南北方向剩余通行时间。
-
'ttdx=shijiannb-sec+5;': 计算东西方向剩余时间。
-
-
'else if(sec>shijiannb&&sec<=(shijiannb+5))': 如果秒数大于南北方向的通行时间且小于等于南北方向黄灯时间,执行以下代码:
-
'state=1;': 设置南北方向黄灯,东西方向红灯。
-
'ttnb=shijiannb-sec+5;': 计算南北方向剩余时间。
-
'ttdx=shijiannb-sec+5;': 计算东西方向剩余时间。
-
-
'else if(sec>(shijiannb+5)&&sec<=(shijiannb+shijiandx+1+5))': 如果秒数大于南北方向黄灯时间且小于等于东西方向绿灯时间,执行以下代码:
-
'state=2;': 设置东西方向绿灯,南北方向红灯。
-
'ttnb=(shijiannb+shijiandx+1)-sec+10;': 计算南北方向剩余时间。
-
'ttdx=(shijiannb+shijiandx+1)-sec+5;': 计算东西方向剩余时间。
-
-
'else if(sec>(shijiannb+shijiandx+6))': 如果秒数大于东西方向绿灯时间,执行以下代码:
-
'state=3;': 设置东西方向黄灯,南北方向红灯。
-
'ttnb=(shijiannb+shijiandx+11)-sec;': 计算南北方向剩余时间。
-
'ttdx=(shijiannb+shijiandx+11)-sec;': 计算东西方向剩余时间。
-
-
-
'else': 如果 'cnt' 计数器未溢出,则 'cnt' 自增 1。
-
'if(state==0)': 如果交通信号灯状态为南北方向绿灯,东西方向红灯,则将 'led' 赋值为 '6'b011_101',表示南北方向绿灯亮,东西方向红灯亮。
-
'else if(state==1)': 如果交通信号灯状态为南北方向黄灯,东西方向红灯,则将 'led' 赋值为 '6'b011_110',表示南北方向黄灯亮,东西方向红灯亮。
-
'else if(state==2)': 如果交通信号灯状态为东西方向绿灯,南北方向红灯,则将 'led' 赋值为 '6'b101_011',表示东西方向绿灯亮,南北方向红灯亮。
-
'else if(state==3)': 如果交通信号灯状态为东西方向黄灯,南北方向红灯,则将 'led' 赋值为 '6'b110_011',表示东西方向黄灯亮,南北方向红灯亮。
-
'data[3:0] =ttnb/10; data[7:4] =ttnb%10; data[11:8] =ttdx/10; data[15:12] =ttdx%10;': 将南北方向剩余时间和东西方向剩余时间输出到数码管。
-
-
'else if(moshi==1)': 如果处于调节时间模式,则将 'led' 赋值为 '6'b111_111',表示所有 LED 灯亮,并将南北方向和东西方向的通行时间输出到数码管。
-
'else if(moshi==2)': 如果处于东西方向通行模式,南北方向禁止通行,则将 'led' 赋值为 '6'b101_011',表示东西方向绿灯亮,南北方向红灯亮,并将所有剩余时间输出到数码管。
-
'else if(moshi==3)': 如果处于南北方向通行模式,东西方向禁止通行,则将 'led' 赋值为 '6'b011_101',表示南北方向绿灯亮,东西方向红灯亮,并将所有剩余时间输出到数码管。
-
'else if(moshi==4)': 如果处于夜间模式,执行以下代码:
-
'if (cnt2 == 24_999_999)': 如果 'cnt2' 计数器溢出,执行以下代码:
-
'cnt2 = 0;': 将 'cnt2' 计数器清零。
-
'if(ff==0)ff=1; else ff=0;': 控制 LED 灯闪烁。
-
-
'else cnt2=cnt2+1;': 如果 'cnt2' 计数器未溢出,则 'cnt2' 自增 1。
-
'if(ff==0) led<= 6'b110_110; else led<= 6'b111_111;': 控制 LED 灯闪烁,并将所有剩余时间输出到数码管。
-
-
'else if(moshi==5)': 如果处于按流量通行模式,执行以下代码:
-
'if (cnt == 49_999_999)': 如果 'cnt' 计数器溢出,执行以下代码:
-
'cnt <= 0;': 将 'cnt' 计数器清零。
-
'if(sec==(shijiannb+shijiandx+11))': 如果秒数大于总通行时间,执行以下代码:
-
'sec=0;': 将秒数清零。
-
'if((nabeiliu>=(dongxiliu+10))&&(nabeiliu<(dongxiliu+20)))': 如果南北方向的流量大于等于东西方向的流量加 10,且小于等于东西方向的流量加 20,则将南北方向通行时间设置为 40,东西方向通行时间设置为 20。
-
'else if((nabeiliu>=(dongxiliu+20)))': 如果南北方向的流量大于等于东西方向的流量加 20,则将南北方向通行时间设置为 60,东西方向通行时间设置为 20。
-
'else if((dongxiliu>=(nabeiliu+10))&&(dongxiliu<(nabeiliu+20)))': 如果东西方向的流量大于等于南北方向的流量加 10,且小于等于南北方向的流量加 20,则将南北方向通行时间设置为 20,东西方向通行时间设置为 40。
-
'else if((dongxiliu>=(nabeiliu+20)))': 如果东西方向的流量大于等于南北方向的流量加 20,则将南北方向通行时间设置为 20,东西方向通行时间设置为 60。
-
'else': 如果以上条件都不满足,则将南北方向通行时间和东西方向通行时间设置为 20。
-
'dongxiliu<=0; nabeiliu<=0;': 清零东西方向和南北方向的流量计数器。
-
-
'else sec=sec+1;': 如果秒数未大于总通行时间,则秒数自增 1。
-
'if(sec<=shijiannb)': 如果秒数小于南北方向的通行时间,执行以下代码:
-
'state=0;': 设置南北方向绿灯,东西方向红灯。
-
'ttnb=shijiannb-sec;': 计算南北方向剩余通行时间。
-
'ttdx=shijiannb-sec+5;': 计算东西方向剩余时间。
-
-
'else if(sec>shijiannb&&sec<=(shijiannb+5))': 如果秒数大于南北方向的通行时间且小于等于南北方向黄灯时间,执行以下代码:
-
'state=1;': 设置南北方向黄灯,东西方向红灯。
-
'ttnb=shijiannb-sec+5;': 计算南北方向剩余时间。
-
'ttdx=shijiannb-sec+5;': 计算东西方向剩余时间。
-
-
'else if(sec>(shijiannb+5)&&sec<=(shijiannb+shijiandx+1+5))': 如果秒数大于南北方向黄灯时间且小于等于东西方向绿灯时间,执行以下代码:
-
'state=2;': 设置东西方向绿灯,南北方向红灯。
-
'ttnb=(shijiannb+shijiandx+1)-sec+10;': 计算南北方向剩余时间。
-
'ttdx=(shijiannb+shijiandx+1)-sec+5;': 计算东西方向剩余时间。
-
-
'else if(sec>(shijiannb+shijiandx+6))': 如果秒数大于东西方向绿灯时间,执行以下代码:
-
'state=3;': 设置东西方向黄灯,南北方向红灯。
-
'ttnb=(shijiannb+shijiandx+11)-sec;': 计算南北方向剩余时间。
-
'ttdx=(shijiannb+shijiandx+11)-sec;': 计算东西方向剩余时间。
-
-
-
'else': 如果 'cnt' 计数器未溢出,则 'cnt' 自增 1。
-
'if(state==0)': 如果交通信号灯状态为南北方向绿灯,东西方向红灯,则将 'led' 赋值为 '6'b011_101',表示南北方向绿灯亮,东西方向红灯亮。
-
'else if(state==1)': 如果交通信号灯状态为南北方向黄灯,东西方向红灯,则将 'led' 赋值为 '6'b011_110',表示南北方向黄灯亮,东西方向红灯亮。
-
'else if(state==2)': 如果交通信号灯状态为东西方向绿灯,南北方向红灯,则将 'led' 赋值为 '6'b101_011',表示东西方向绿灯亮,南北方向红灯亮。
-
'else if(state==3)': 如果交通信号灯状态为东西方向黄灯,南北方向红灯,则将 'led' 赋值为 '6'b110_011',表示东西方向黄灯亮,南北方向红灯亮。
-
'data[3:0] =ttnb/10; data[7:4] =ttnb%10; data[11:8] =ttdx/10; data[15:12] =ttdx%10;': 将南北方向剩余时间和东西方向剩余时间输出到数码管。
-
-
-
'always @(posedge CLOCK_50)': 当时钟信号上升沿时,执行以下代码。
-
'if(moshi==5)': 如果处于按流量通行模式,则将南北方向和东西方向的流量计数器输出到数码管。
-
'else': 如果不处于按流量通行模式,则将当前模式输出到数码管。
-
-
'endmodule': 结束模块定义。
该代码模块通过检测流量传感器和按键输入,控制交通信号灯的显示,并根据不同的模式进行不同的控制。例如,在默认模式下,交通信号灯按照预设的通行时间交替闪烁。在按流量通行模式下,交通信号灯根据南北方向和东西方向的流量大小来调整通行时间。
代码中使用了多个计数器和状态机来实现交通信号灯的控制逻辑。此外,代码还使用了按键消抖模块来防止按键抖动带来的误操作。
这段代码可以作为学习 Verilog 语言和交通信号灯控制逻辑的参考。
原文地址: https://www.cveoy.top/t/topic/ofb3 著作权归作者所有。请勿转载和采集!