题解主体

格雷码计数器,分为三部分进行设计,格雷码转二进制、加法器、二进制转格雷码。 

格雷码转二进制将格雷码转换为二进制,并将值输出用于加法器进行加法运算,然后将加法运算结果通过二进制转格雷码转换为格雷码,最后将格雷码进行输出,同时将结果输出到格雷码转二进制作为输入,形成一个计数功能。 

格雷码转二进制码的基本思路:

格雷码转二进制是从左边第二位起,将每位与左边一位二进制码的值异或,作为该位二进制码后的值(最左边一位依然不变)。

二进制码转格雷码的基本思路:

从最右边一位起,依次将每一位与左边一位异或(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