本帖最后由 hjl240 于 2014-1-24 19:49 编辑
程序如下:
module led_test(
clk,
rst_n,
led
);
input clk;//100MHz
input rst_n;//低电平复位信号
output[7:0]led;
reg[22:0] cnt;//分频信号
always @(posedge clk or negedge rst_n)
if(!rst_n)cnt<=23'd0;
elsecnt<=cnt+1'b1;
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左移一次
assign led=ledr;
endmodule
端口分配情况如下:
下面对程序进行简单分析一下:
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 信号=表达式;
注意:体会一下“赋值语句”用“<=”与“=”的区别。
如果有什么地方说的不好或者不对,可以提出来讨论讨论一下。
附:pdf版的文字以及整个工程。