该模块名为 'control',包含多个输入和输出端口。

输入端口:

  • CLOCK_50: 板载 50MHz 时钟。
  • Q_KEY: 按键输入。
  • guang1: 南北方向流量传感器接口。
  • guang2: 东西方向流量传感器接口。
  • KEY: 按键输入,9 位。 输出端口:
  • data: 显示时间和模式,16 位。
  • liul: 显示流量信息,16 位。
  • led: 控制红绿灯,6 位。

其中,'nabeiliu' 和 'dongxiliu' 是用于计数流量的寄存器,'F1'、'F2'、'F3' 和 'F4' 是用于检测时钟的上升沿和下降沿的寄存器。'cnt1'、'cnt' 和 'cnt2' 是用于计数时间的寄存器。't_buf1' 和 't_buf2' 是用于暂存流量值的寄存器。'moshi' 是用于控制不同模式的寄存器。'shijiandx' 和 'shijiannb' 是用于控制南北和东西方向信号灯时间的寄存器。'state' 是用于控制当前红绿灯状态的寄存器。'sec'、'ttnb' 和 'ttdx' 是用于计算时间和显示时间的寄存器。'ff' 是用于夜间模式的寄存器。

代码解析

1. 时钟检测

reg F1,F2;
always @(posedge CLOCK_50 or negedge Q_KEY)
if(!Q_KEY)
begin
    F1<=1'b1;
    F2<=1'b1;
end
else
begin
    F1<=guang1;//需要检测的引脚
    F2<=F1;
end
assign   SCK_fallingedge1  = F2 && !F1;//检测时钟的下降沿
assign   SCK_risingedge1 = F1 && !F2;//检测时钟的上升沿

这段代码利用两个寄存器 'F1' 和 'F2' 来检测时钟的上升沿和下降沿。当按下 'Q_KEY' 时,'F1' 和 'F2' 都被置为 '1'。当 'Q_KEY' 松开后,'F1' 的值会被 'guang1' 的值更新,而 'F2' 则保留 'F1' 的前一个值。通过比较 'F1' 和 'F2' 的值,可以检测出时钟的上升沿和下降沿。

2. 流量计数

reg [7:0] nabeiliu;  
reg [7:0] dongxiliu;   
reg  uu1; 
reg  uu2; 

always @ (posedge CLOCK_50, negedge Q_KEY)
  if (!Q_KEY)
    begin
      nabeiliu<=0;
      dongxiliu<=0;
      ...
    end
  else 
	begin 	
    ...
        if(SCK_fallingedge1 == 1)
		begin 
			uu1=1;		    
		end 
        if(SCK_fallingedge2 == 1)
		begin 
			uu2=1;		    
		end 				
		if (cnt1 == 9_999_999)
		  begin
				cnt1 <= 0;				
                if(guang1==1&&uu1==1)
				begin 
					uu1<=0;
					nabeiliu<=nabeiliu+1;			    
				end 				
                if(guang2==1&&uu2==1)
				begin 
					uu2<=0;
					dongxiliu<=dongxiliu+1;			    
				end 							
		  end
		else
		cnt1 <= cnt1 + 1'b1;    
    ...
    end

这段代码利用两个寄存器 'nabeiliu' 和 'dongxiliu' 来计数南北方向和东西方向的流量。当检测到 'guang1' 和 'guang2' 的值发生变化时,并且对应时钟的下降沿被检测到,相应的计数器就会加 1。

3. 模式控制

reg [3:0] moshi; 		

always @ (posedge CLOCK_50, negedge Q_KEY)
  if (!Q_KEY)
    begin
      ...
      moshi=0; 
      ...
    end
  else 
	begin 	
    ...
	  case (1'b0)
		  key_val[1] : 
			begin 
			    moshi=1;//调节时间
			    ...
			end 
		  key_val[2] : 
			begin 
			    moshi=1;//调节时间
			    ...
			end 		  
		  key_val[3] : 
			begin 
			    moshi=1;//调节时间
			    ...
			end 
		  key_val[4] : 
			begin 
			    moshi=1;//调节时间
			    ...
			end 
		  key_val[5] : 
			begin 
			    moshi=2;//东西方向通行,南北禁止	
			    ...
			end 				
		  key_val[6] : 
			begin 
			    moshi=3;
			    ...
			end 	
		  key_val[7] : 
			begin 
			    moshi=4;
			    ...
			end 				
		  key_val[8] : 
			begin 
			    moshi=5;shijiannb=20;shijiandx=20;	
			    ...
			end 	
		  key_val[9] : 
			begin 
			    moshi=0;	
			    ...
			end 										
				
		endcase      
    ...
    end

这段代码利用 'moshi' 寄存器来控制不同的模式。通过按下不同的按键,可以改变 'moshi' 的值,从而切换不同的工作模式。

4. 时间控制

reg [6:0] shijiandx,shijiannb; 
reg [6:0] ttdx,ttnb; 

always @ (posedge CLOCK_50, negedge Q_KEY)
  if (!Q_KEY)
    begin
      ...
      shijiandx=20; 
      shijiannb=20; 
      ...
    end
  else 
	begin 	
    ...
    if(moshi==0)
      		    begin
		                

					  if (cnt == 49_999_999)  //1s
					  begin
							cnt <= 0;	
							if(sec==(shijiannb+shijiandx+11))sec=0;
							else sec=sec+1;
				            if(sec<=shijiannb)//南北通行;东西禁止
				            begin
					              state=0;
                                  ttnb=shijiannb-sec;
                                  ttdx=shijiannb-sec+5;
					        
					        end
					        else if(sec>shijiannb&&sec<=(shijiannb+5))//南北黄灯5S;东西禁止
				            begin
					              state=1;
                                  ttnb=shijiannb-sec+5;
                                  ttdx=shijiannb-sec+5;					             
					        end	
					        else if(sec>(shijiannb+5)&&sec<=(shijiannb+shijiandx+1+5))//东西通行;南北禁止
				            begin
					             state=2;
                                  ttnb=(shijiannb+shijiandx+1)-sec+10;
                                  ttdx=(shijiannb+shijiandx+1)-sec+5;					             
					             
					        end						        
					        else if(sec>(shijiannb+shijiandx+6))//东西黄灯5S;南北禁止
				            begin
					             state=3;
                                  ttnb=(shijiannb+shijiandx+11)-sec;
                                  ttdx=(shijiannb+shijiandx+11)-sec;						        
					        end							        				        
					  end
					  else		  
					  cnt <= cnt + 1'b1; 						  
					  ...
		        end
		        else if(moshi==1)//调节时间
      		    begin
		              ...
					  data[3:0]   =shijiannb/10;
					  data[7:4]   =shijiannb%10;
					  data[11:8]  =shijiandx/10;
					  data[15:12] =shijiandx%10;  				            
		        end
		        else if(moshi==5)//按流量通行模式
      		    begin
		        
	              if (cnt == 49_999_999)  //1s
					  begin
							cnt <= 0;	
							if(sec==(shijiannb+shijiandx+11))
							begin
							      sec=0;
							      ...
							end
							else sec=sec+1;
				            if(sec<=shijiannb)//南北通行;东西禁止
				            begin
					              state=0;
                                  ttnb=shijiannb-sec;
                                  ttdx=shijiannb-sec+5;
					        
					        end
					        ...
					  end
					  else		  
					  cnt <= cnt + 1'b1; 						  
					  ...
		        
		        end		        		         	
    	
    	     
    end

这段代码利用多个寄存器来控制时间和显示时间。'shijiandx' 和 'shijiannb' 用于控制南北和东西方向的信号灯时间。'sec' 用于记录当前秒数。'ttnb' 和 'ttdx' 用于计算剩余时间并显示在 'data' 输出端口上。

5. 红绿灯控制

reg [2:0] state; 

always @ (posedge CLOCK_50, negedge Q_KEY)
  if (!Q_KEY)
    begin
      ...
    end
  else 
	begin 	
    ...
    if(moshi==0)
      		    begin
		                

					  if (cnt == 49_999_999)  //1s
					  begin
							cnt <= 0;	
							if(sec==(shijiannb+shijiandx+11))sec=0;
							else sec=sec+1;
				            if(sec<=shijiannb)//南北通行;东西禁止
				            begin
					              state=0;
                                  ...
					        
					        end
					        else if(sec>shijiannb&&sec<=(shijiannb+5))//南北黄灯5S;东西禁止
				            begin
					              state=1;
                                  ...
					             
					        end	
					        else if(sec>(shijiannb+5)&&sec<=(shijiannb+shijiandx+1+5))//东西通行;南北禁止
				            begin
					             state=2;
                                  ...
					             
					        end						        
					        else if(sec>(shijiannb+shijiandx+6))//东西黄灯5S;南北禁止
				            begin
					             state=3;
                                  ...
					        end							        				        
					  end
					  else		  
					  cnt <= cnt + 1'b1; 						  
					  
					  if(state==0)
					  begin					       
						  led<= 6'b011_101;//东西方向:红绿黄 南北方向:红绿黄 			              		              
		              end
					  else if(state==1)
					  begin				       
						  led<= 6'b011_110;//东西方向:红绿黄 南北方向:红绿黄 			              		              
		              end		              
					  else  if(state==2)
					  begin					       
						  led<= 6'b101_011;//东西方向:红绿黄 南北方向:红绿黄 			              		              
		              end
					  else if(state==3)
					  begin					       
						  led<= 6'b110_011;//东西方向:红绿黄 南北方向:红绿黄 			              		              
		              end	
					  ...
		        end
		        ...
    end

这段代码利用 'state' 寄存器来控制当前红绿灯的状态。根据不同的时间段,'state' 会被更新,从而控制 'led' 输出端口的输出值,实现红绿灯的切换。

6. 流量信息显示

always @ (posedge CLOCK_50)
   begin
   
  if(moshi==5)
  begin
    liul[3:0]  <= nabeiliu/10; //南北方向流量 十位
   liul[7:4]   <= nabeiliu%10;//南北方向流量 个位
   liul[11:8]  <= dongxiliu/10;//东西方向流量 十位
   liul[15:12] <= dongxiliu%10; //东西方向流量 个位  
  end
  else 
  begin
   liul[3:0]   <= moshi; 
   liul[7:4]   <= 10;
   liul[11:8]  <= 10;
   liul[15:12] <= 10;   
  end
   
   end

这段代码将南北方向和东西方向的流量值分别显示在 'liul' 输出端口上。当 'moshi' 等于 5 时,显示实际流量值。其他模式下,显示 'moshi' 的值。

总结

这段 Verilog 代码实现了交通灯控制模块,包括流量计数、模式控制、时间控制和红绿灯显示等功能。代码逻辑清晰,结构简洁,易于理解和维护。

Verilog 代码详解:交通灯控制模块

原文地址: https://www.cveoy.top/t/topic/ofbH 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录