//led 1S实验
//使用分屏实验1s计数
`timescale 1ns/1ps
module vlg_design(
input i_clk,
input i_rest_n,
input[7:0] key,
output reg[7:0] led
);
`define CNT_1S_DEBUG
`ifndef CNT_1S_DEBUG
parameter CNT_1S_MAX = 1_000_000_000/20 - 1;
`else /*CNT_1S_DEBUG*/
parameter CNT_1S_MAX = 1_000/20 - 1;
`endif
reg [27:0] r_cnt_1s;
reg [3:0] r_i_para;
reg r_cnt1s_flag;
wire [3:0] w_i_para;
always @(posedge i_clk) begin
if(!i_rest_n) r_cnt_1s <= 'd0;
else if(r_cnt_1s < CNT_1S_MAX) r_cnt_1s <= r_cnt_1s+1;
else r_cnt_1s <= 'd0;
end
always @(posedge i_clk) begin
if(!i_rest_n) r_i_para <= 'b0;
else if(r_i_para == 8) r_i_para <= 'b0;
else if (r_cnt_1s == CNT_1S_MAX) r_i_para <= r_i_para+1;
else ;
end
always @(posedge i_clk) begin
if(!i_rest_n) r_cnt1s_flag <= 'b0;
else if (r_cnt_1s == CNT_1S_MAX) r_cnt1s_flag <= 1;
else r_cnt1s_flag <= 'b0;
end
always @(posedge i_clk) begin
if(!i_rest_n) led <= 'b0;
else if (r_cnt1s_flag) led <= (1 << w_i_para-1);
else ;
end
assign w_i_para = r_cnt1s_flag?r_i_para:w_i_para;
endmodule
另外移位还可以通过以下方式实现if(cnt == MAX_CNT) led <= {led[6:0],led[7]};
//计数器cnt计数到最大值时,切换点亮的指示灯
always @ (posedge sys_clk_i or negedge ext_rst_n)
if(!ext_rst_n) led <= 8'b1111_1110; //默认只点亮一个指示灯D2
else if(cnt == MAX_CNT) led <= {led[6:0],led[7]}; //200ms为一个计数周期,执行一次循环移位操作
else ;
`timescale 1ns/1ps
module testbench_top();
//参数定义
`define CLK_PERIORD 20 //时钟周期设置为20ns(50MHz)
//接口申明
reg i_clk;
reg i_rest_n;
reg [7:0] key;
wire [7:0] led;
//对被测试的设计进行例化
vlg_design uut_vlg_design(
.i_clk(i_clk),
.i_rest_n(i_rest_n),
.key(key),
.led(led)
);
///
integer i;
initial begin
key <= 8'b11111111;
i_clk <= 0;
i_rest_n <= 0;
#20;
i_rest_n <= 1;
end
always #(`CLK_PERIORD/2) i_clk = ~i_clk;
initial begin
@(posedge i_clk);
@(posedge i_rest_n);
for(i = 0;i < 8;i = i+1) begin
key <= ~(1<<i);
repeat(2) @(posedge i_clk);
end
#200_000_000;
$stop;
end
endmodule