题解主体
格雷码计数器,分为三部分进行设计,格雷码转二进制、加法器、二进制转格雷码。
格雷码转二进制将格雷码转换为二进制,并将值输出用于加法器进行加法运算,然后将加法运算结果通过二进制转格雷码转换为格雷码,最后将格雷码进行输出,同时将结果输出到格雷码转二进制作为输入,形成一个计数功能。
格雷码转二进制码的基本思路:
格雷码转二进制是从左边第二位起,将每位与左边一位二进制码的值异或,作为该位二进制码后的值(最左边一位依然不变)。
二进制码转格雷码的基本思路:
从最右边一位起,依次将每一位与左边一位异或(XOR),作为对应格雷码该位的值,最左边一位不变。
Verilog代码描述如下:
module gray_counter( input clk, input rst_n, output reg [3:0] gray_out ); //格雷码转二进制 reg [3:0] bin_out; wire [3:0] gray_wire; always @(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) begin bin_out <= 4'b0; end else begin bin_out[3] = gray_wire[3]; bin_out[2] = gray_wire[2]^bin_out[3]; bin_out[1] = gray_wire[1]^bin_out[2]; bin_out[0] = gray_wire[0]^bin_out[1]; end end //二进制加一 reg [3:0] bin_add_wire; always @(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) begin bin_add_wire <= 4'b0; end else begin bin_add_wire <= bin_out + 1'b1; end end //二进制转格雷码 assign gray_wire = (bin_add_wire >> 1) ^ bin_add_wire; always @(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) begin gray_out <= 4'b0; end else begin gray_out <= gray_wire; end end endmodule
参考答案
`timescale 1ns/1ns module gray_counter( input clk, input rst_n, output reg [3:0] gray_out ); //格雷码转二进制 reg [3:0] bin_out; wire [3:0] gray_wire; always @(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) begin bin_out <= 4'b0; end else begin bin_out[3] = gray_wire[3]; bin_out[2] = gray_wire[2]^bin_out[3]; bin_out[1] = gray_wire[1]^bin_out[2]; bin_out[0] = gray_wire[0]^bin_out[1]; end end //二进制加一 reg [3:0] bin_add_wire; always @(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) begin bin_add_wire <= 4'b0; end else begin bin_add_wire <= bin_out + 1'b1; end end //二进制转格雷码 assign gray_wire = (bin_add_wire >> 1) ^ bin_add_wire; always @(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) begin gray_out <= 4'b0; end else begin gray_out <= gray_wire; end end endmodule