一个简单的Verilog计数器模型
功能说明:
- 向上计数
- 向下计数
- 预装载值
一、代码
1.counter代码(counter.v)
1 module counter( 2 input clk, 3 input rstn, 4 input go, //使能启动信号 5 input [3:0] data, //预装载数据 6 input load, //预装载信号 7 input dir, //计数方向 8 9 output reg [3:0] cnt, //计数输出值 10 output overfloat, //向上溢出 11 output downfloat //向下溢出 12 ); 13 14 reg [3:0] cnt_next; 15 reg [3:0] data_shadow; 16 17 always@(posedge clk,negedge rstn) 18 begin 19 if(!rstn) 20 data_shadow <= 4'b0; 21 else 22 data_shadow <= data; 23 end 24 25 always@(posedge clk,negedge rstn) 26 begin 27 if(!rstn) 28 cnt <= 4'b0; 29 else 30 cnt <= cnt_next; 31 end 32 33 always@(*) 34 begin 35 if(go) 36 begin 37 if(load && overfloat) 38 cnt_next = 4'b0; 39 else if(load && downfloat) 40 cnt_next = data_shadow; 41 else 42 if(dir) 43 cnt_next = cnt + 1'b1; 44 else 45 cnt_next = cnt - 1'b1; 46 end 47 else 48 cnt_next = cnt; 49 end 50 51 assign overfloat = (dir && (cnt == data_shadow)); 52 assign downfloat = (!dir && (cnt == 4'b0)); 53 54 endmodule
2、testbench(counter_tb.v)
1 module counter_tb; 2 3 reg clk; 4 reg rstn; 5 reg go; 6 reg [3:0] data; 7 reg load; 8 reg dir; 9 10 wire [3:0] cnt; 11 wire overfloat; 12 wire downfloat; 13 14 initial 15 begin 16 clk = 0; 17 18 rstn = 1; 19 repeat(20) @(posedge clk); 20 rstn = 0; 21 repeat(80) @(posedge clk); 22 rstn = 1; 23 24 25 go = 0; 26 data = 4'b0000; 27 load = 0; 28 dir = 0; 29 30 @(posedge clk); 31 data = 4'b0000; 32 load = 0; 33 dir = 0; 34 go = 1; 35 36 repeat(100) @(posedge clk); 37 data = 4'b0000; 38 load = 0; 39 dir = 1; 40 go = 1; 41 42 repeat(100) @(posedge clk); 43 data = 4'b1001; 44 load = 1; 45 dir = 0; 46 go = 1; 47 48 repeat(100) @(posedge clk); 49 data = 4'b1001; 50 load = 0; 51 dir = 1; 52 go = 1; 53 54 repeat(100) @(posedge clk); 55 $finish; 56 end 57 63 always #20 clk = ~clk; 64 65 counter u_counter( 66 .clk(clk), 67 .rstn(rstn), 68 .go(go), 69 .data(data), 70 .load(load), 71 .dir(dir), 72 .cnt(cnt), 73 .overfloat(overfloat), 74 .downfloat(downfloat) 75 ); 76 77 endmodule
二、仿真结果
向下计数
向上计数
预装载向下计数
预装载向上计数