reg[2:0] key_rst;
always @(posedge clk or negedge rst_n)
if (!rst_n) key_rst <= 3'b111;
else key_rst <= {sw3_n,sw2_n,sw1_n};
reg[2:0] key_rst_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中
always @( posedge clk or negedge rst_n)
if (!rst_n) key_rst_r <= 3'b111;
else key_rst_r <= key_rst;
//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
wire[2:0] key_an = key_rst_r & ( ~key_rst);
由于相差一个时钟周期最终key_an变为1,但是两个always之间是并行的啊,怎么会相差一个时钟周期呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
clk,rst_n,
key1,key2,key3,
led0,led1,led2,led3
);
input clk; //主时钟,50MHz
input rst_n; //低电平复位
input key1,key2,key3; // 按键接口
output led0,led1,led2,led3; // LED等接口
//------------------------------------
reg[23:0] delay; //延时计数器
always @ (posedge clk or negedge rst_n)
if(!rst_n) delay <= 0;
else delay <= delay+1; //不断计数,周期为320ms
reg[2:0] key_value; //键值寄存器
always @ (posedge clk or negedge rst_n)
if(!rst_n) key_value <= 3'b111;
else if(delay == 24'hffffff) key_value <= {key3,key2,key1}; //delay 320ms,锁定键值
//-------------------------------------
reg[2:0] key_value_r;
always @ (posedge clk or negedge rst_n)
if(!rst_n) key_value_r <= 3'b111;
else key_value_r <= key_value;
wire[2:0] key_change; //判定前后20ms的键值是否发生了改变,若是,则key_change置高
assign key_change = key_value_r & (~key_value); //check key_value negedge per clk
//------------------------------------
reg stop_start,left_right; //流水灯控制位
always @ (posedge clk or negedge rst_n)
if(!rst_n) begin
stop_start <= 1;
left_right <= 1;
end
else
if(key_change[2]) stop_start <= ~stop_start; //开始结束控制位
else if(key_change[1]) left_right <= 1; //流水灯方向控制
else if(key_change[0]) left_right <= 0; //流水灯方向控制
//-------------------------------------
reg[3:0] led_value_r; // LED值寄存器
always @ (posedge clk or negedge rst_n)
if(!rst_n) led_value_r <= 4'b1110;
else if(delay == 24'h3fffff && stop_start) //流水灯控制
case (left_right) //方向控制
1: led_value_r <= {led_value_r[2:0],led_value_r[3]}; //右移
0: led_value_r <= {led_value_r[0],led_value_r[3:1]}; //左移
default: ;
endcase
assign {led3,led2,led1,led0} = ~led_value_r;
endmodule
clk,rst_n,
sm_cs1_n,sm_cs2_n,sm_db
);
input clk; // 50MHz
input rst_n; // 复位信号,低有效
output sm_cs1_n,sm_cs2_n; //数码管片选信号,低有效
output[6:0] sm_db; //7段数码管(不包括小数点)
reg[24:0] cnt; //计数器,最大可以计数到2的25次方*20ns=640ms
always @ (posedge clk or negedge rst_n)
if(!rst_n) cnt <= 25'd0;
else cnt <= cnt+1'b1; //循环计数
reg[3:0] num; //显示数值
always @ (posedge clk or negedge rst_n)
if(!rst_n) num <= 4'd0;
else if(cnt == 24'hffffff) num <= num+1'b1; //每640ms增一
//-------------------------------------------------------------------------------
/* 共阴极 :不带小数点
;0, 1, 2, 3, 4, 5, 6, 7,
db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h
;8, 9, a, b, c, d, e, f , 灭
db 7fh,6fh,77h,7ch,39h,5eh,79h,71h,00h*/
parameter seg0 = 7'h3f,
seg1 = 7'h06,
seg2 = 7'h5b,
seg3 = 7'h4f,
seg4 = 7'h66,
seg5 = 7'h6d,
seg6 = 7'h7d,
seg7 = 7'h07,
seg8 = 7'h7f,
seg9 = 7'h6f,
sega = 7'h77,
segb = 7'h7c,
segc = 7'h39,
segd = 7'h5e,
sege = 7'h79,
segf = 7'h71;
reg[6:0] sm_dbr; //7段数码管(不包括小数点)
always @ (num)
case (num) //NUM值显示在两个数码管上
4'h0: sm_dbr <= seg0;
4'h1: sm_dbr <= seg1;
4'h2: sm_dbr <= seg2;
4'h3: sm_dbr <= seg3;
4'h4: sm_dbr <= seg4;
4'h5: sm_dbr <= seg5;
4'h6: sm_dbr <= seg6;
4'h7: sm_dbr <= seg7;
4'h8: sm_dbr <= seg8;
4'h9: sm_dbr <= seg9;
4'ha: sm_dbr <= sega;
4'hb: sm_dbr <= segb;
4'hc: sm_dbr <= segc;
4'hd: sm_dbr <= segd;
4'he: sm_dbr <= sege;
4'hf: sm_dbr <= segf;
default: ;
endcase
assign sm_db = sm_dbr;
assign sm_cs1_n = 1'b0; //数码管1常开
assign sm_cs2_n = 1'b0; //数码管2常开
endmodule
module mux16(
clk,rst_n,
start,ain,bin,yout,done
);
input clk; //芯片的时钟信号。
input rst_n; //低电平复位、清零信号。定义为0表示芯片复位;定义为1表示复位信号无效。
input start; //芯片使能信号。定义为0表示信号无效;定义为1表示芯片读入输入管脚得乘数和被乘数,并将乘积复位清零。
input[15:0] ain; //输入a(被乘数),其数据位宽为16bit.
input[15:0] bin; //输入b(乘数),其数据位宽为16bit.
output[31:0] yout; //乘积输出,其数据位宽为32bit.
output done; //芯片输出标志信号。定义为1表示乘法运算完成.
reg[15:0] areg; //乘数a寄存器
reg[15:0] breg; //乘数b寄存器
reg[31:0] yout_r; //乘积寄存器
reg done_r;
reg[4:0] i; //移位次数寄存器
always@(posedge clk)
begin
if(!rst_n) begin
areg <= 16'h0000;
breg <= 16'h0000;
done_r <= 1'b0;
yout_r <= 32'h00000000;
i <= 5'd0;
end
else if(start) //启动运算
begin
if(i < 5'd21) i <= i+1'b1;
if(i == 5'd0) begin //锁存乘数、被乘数
areg <= ain;
breg <= bin;
end
else if(i > 5'd0 && i < 5'd16) begin
if(areg[i-1]) yout_r = {1'b0,yout[30:15]+breg,yout_r[14:1]}; //累加并移位
else yout_r <= yout_r>>1; //移位不累加
end
else if(i == 5'd16 && areg[15]) yout_r[31:16] <= yout_r[31:16]+breg; //累加不移位
else if(i == 5'd18) done_r <= 1'b1; //乘完成标志位置位
else if(i == 5'd20) done_r <= 1'b0; //乘完成标志位清除
end
else i <= 5'd0;
end
assign done = done_r;
assign yout = yout_r;
endmodule
ain:0000000001011001 89
bin:0000000000100001 33
yout_r = {1b0,yout[30:15]+breg,yout_r[14:1]};
00084000:00000000000010000100000000000000
00042000:00000000000001000010000000000000
00021000:00000000000000100001000000000000
00094800:00000000000010010100100000000000
000ce400:00000000000011001110010000000000
00067200:00000000000001100111001000000000
000b7900:00000000000010110111100100000000
0005bc80:00000000000001011011110010000000
0002de40:00000000000000101101111001000000
00016f20:00000000000000010110111100100000
0000b790:00000000000000001011011110010000
00005bc8:00000000000000000101101111001000
00002de4:00000000000000000010110111100100
000016f2:00000000000000000001011011110010
00000b79:00000000000000000000101101111001
一周热门 更多>