普通的二进制计数器
电路设计
行为仿真
普通的格雷码计数器
电路设计
行为仿真
LFSR
电路设计
行为仿真
多功能计数器
电路设计
行为仿真
生成语句实现方式
注意事项
写在前面
相关博文[1]博客首页[2]注:学习交流使用!
正文
多功能计数器,英文名为:多功能计数器;所谓多功能,这里包括二进制计数,格雷码计数以及线性反馈移位寄存器(LFSR)三种,本文通过从普通的计数器开始,也就是单个功能的计数器开始,一步一步过渡到多功能计数器。作为对以下相关博文的延伸练习:Verilog设计实例(1)线性反馈移位寄存器(LFSR)[3]FPGA设计心得(8)Verilog中的编译预处理语句[4]
普通的二进制计数器
这个作为开头,不必多说,计数就完事了。
电路设计
设计文件:
`timescale 1ns/1ps
//
// Engineer: Reborn Lee
// Module Name: binary counter
// Additional Comments:
//
//
module binary_counter#(parameter N_BITS = 4)(
input i_clk,
input i_rst,
output [N_BITS - 1 : 0] o_cnt,
output o_cnt_done
);
reg [N_BITS - 1 : 0] bin_cnt = 0;
always@(posedge i_clk) begin
if(i_rst) begin
bin_cnt <= 0;
end
else begin
bin_cnt <= bin_cnt + 1;
end
end
assign o_cnt_done = (bin_cnt == 0)? 1:0;
assign o_cnt = bin_cnt;
endmodule
行为仿真
tb文件:
`timescale 1ns/1ps
module bin_cnt_tb;
parameter N_BITS = 4;
reg i_clk;
reg i_rst;
wire [N_BITS - 1 : 0] o_cnt;
wire o_cnt_done;
initial begin
i_clk = 0;
forever begin
# 2 i_clk = ~ i_clk;
end
end
initial begin
i_rst = 1;
# 8
i_rst = 0;
end
binary_counter #(.N_BITS(N_BITS))
inst_bin_cnt(
.i_rst(i_rst),
.i_clk(i_clk),
.o_cnt(o_cnt),
.o_cnt_done(o_cnt_done)
);
endmodule
仿真图:
普通的格雷码计数器
任意位宽的格雷码计数器,实现的方式通常是设计一个普通的二进制计数器,同时将计数结果转化为格雷码。二进制与格雷码的转换方式,详情见:格雷码和二进制转换[5]。为了方便给出原理图:伪代码描述为:
assign gray_value = binary_value ^ (binary_value>>1);
或者:
assign gray_cnt = { bin_cnt[N_BITS - 1], bin_cnt[N_BITS - 1 : 1]^bin_cnt[N_BITS - 2 : 0]};
电路设计
一种简单的设计方式为:
`timescale 1ns / 1ps
//
// Engineer: Reborn Lee
// Create Date: 2020/06/02 13:46:10
// Module Name: gray_counter
// Additional Comments: common gray counter
//
//
module gray_counter #(parameter N_BITS = 4)(
input i_clk,
input i_rst,
output [N_BITS - 1 : 0] o_cnt,
output o_cnt_done
);
reg [N_BITS - 1 : 0] bin_cnt = 0;
reg [N_BITS - 1 : 0] gray_cnt;
always@(posedge i_clk) begin
if(i_rst) begin
bin_cnt <= 0;
gray_cnt <= 0;
end
else begin
bin_cnt <= bin_cnt + 1;
// translate binary counter into gray counter
gray_cnt <= bin_cnt ^ bin_cnt >>> 1;
//or
// gray_cnt <= { bin_cnt[N_BITS - 1], bin_cnt[N_BITS - 1 : 1]^bin_cnt[N_BITS - 2 : 0]};
//or
// for(int i = 0; i < N_BITS - 1; i = i + 1) begin
// gray_cnt[i] <= bin_cnt[i+1]^bin_cnt[i];
// end
// gray_cnt[N_BITS - 1] <= bin_cnt[N_BITS - 1