EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
(本文适合 FPGA及Verilog初学者,大牛们可以直接忽略)上一次已经讲过如何实现点亮全部的LED,这次分享一下如何实现简单的流水灯。 程序如下: module led_test( clk, rst_n, led ); input clk;//100MHz input rst_n;//低电平复位信号 output[7:0]led; : W$ q$ R) V' H: {' u8 C' v$ I' B
reg[22:0] cnt;//分频信号
% v ^& M O) |always @(posedge clk or negedge rst_n) if(!rst_n)cnt<=23'd0; elsecnt<=cnt+1'b1; - `' h* S3 I K4 |. D, c- v
reg[7:0] ledr; always @(posedge clk or negedge rst_n) if(!rst_n)ledr<=8'd1; elseif(cnt==23'h7fffff) ledr<={ledr[6:0],ledr[7]}; //7fffff(16进制)=8388607(十进制)8388607/100MHz约等于83ms,即每83ms左移一次 1 j0 [& l! R- I$ Y+ [' q
assign led=ledr;
7 Y5 p4 _! u0 ` K! H$ t8 I2 r' ^8 U
endmodule : I% \& w3 ^, F! t" ?4 w+ a, ?0 h
端口分配情况如下:
- ^) l' D1 B* D: L9 i& P# q- P3 G
# v1 ?+ f8 l) k V+ U/ h1 g* P
$ C2 v/ Y7 ]( ]& `# N9 D" p% g
! f5 `& ]3 {5 s6 F% }( T: q+ C
# Y2 I! d1 u0 s: n5 \( }" e. i
下面对程序进行简单分析一下: 1. reg[22:0] cnt;//分频信号 always @(posedge clk or negedge rst_n) if(!rst_n) cnt<=23'd0; else cnt<=cnt+1'b1; cnt用于计数,在每个时钟的上升沿(posedgeclk)或者复位信号的下降沿(negedge rst_n)到来时,如果复位电平rst_n为高(1),则cnt自加1,如果复位电平rst_n为低(0),则cnt为0. 2. always @(posedge clk or negedgerst_n) if(!rst_n)ledr<=8'd1; else if(cnt==23'h7fffff) ledr<={ledr[6:0],ledr[7]}; 两个always语句是同时进行的,当cnt计数到7fffff时,ledr进行左移一位。 { }为连接运算符,连接操作是将小表达式合并形成大表达式的操作。 形式如下:{expr1, expr2, . . .,exprN}比如,ledr[6:0]=0010000,ledr[7]=0,则,ledr<=00100000。那么下一次再进入时,ledr[6:0]=0100000,ledr[7]=0,ledr<=01000000,因此实现了左移功能。 3. assign led=ledr;assign语句是连续赋值语句,它用于对wire型的变量赋值。 用assign语句描述逻辑功能的基本格式如下:assign 信号=表达式; 0 D1 o% B" D5 M: u* a3 ]; U5 D+ n8 T! ^
注意:体会一下“赋值语句”用“<=”与“=”的区别。
- s ~$ y+ {5 u7 x+ [, S
如果有什么地方说的不好或者不对,可以提出来讨论讨论一下。 % ]& r# g! k8 V7 X" u' Q: j
附:pdf版的文字以及整个工程。
@6 S* g& B% l |