格雷码计数器
题目描述
实现4bit位宽的格雷码计数器。
电路的接口如下图所示
题目解读
格雷码计数器,分为三部分进行设计,格雷码转二进制、加法器、二进制转格雷码。
格雷码转二进制将格雷码转换为二进制,并将值输出用于加法器进行加法运算,然后将加法运算结果通过二进制转格雷码转换为格雷码,最后将格雷码进行输出,同时将结果输出到格雷码转二进制作为输入,形成一个计数功能。
格雷码转二进制码的基本思路:
格雷码转二进制是从左边第二位起,将每位与左边一位二进制码的值异或,作为该位二进制码后的值(最左边一位依然不变)。
二进制码转格雷码的基本思路:
从最右边一位起,依次将每一位与左边一位异或(XOR),作为对应格雷码该位的值,最左边一位不变。
`timescale 1ns/1nsmodule 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)beginif(rst_n == 1'b0) beginbin_out <= 4'b0;endelse beginbin_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)beginif(rst_n == 1'b0) beginbin_add_wire <= 4'b0;endelse beginbin_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)beginif(rst_n == 1'b0) begingray_out <= 4'b0;endelse begingray_out <= gray_wire;end
end
endmodule
方法二
`timescale 1ns/1nsmodule gray_counter(input clk,input rst_n,output reg [3:0] gray_out
);reg[4:0] count;reg rev;always@(posedge clk or negedge rst_n)if(!rst_n)count <= 5'b0;elsecount <= count + 1'b1;always@(*)if(!rst_n)gray_out = 4'b0;elsegray_out = count[4:1] ^ (count[4:1] >> 1);endmodule
方法三
`timescale 1ns/1nsmodule gray_counter(input clk,input rst_n,output wire [3:0] gray_out
);//使用Moore状态机实现parameter s0 =8'b0000_0000,s1 = 8'b0001_0001,s2 = 8'b0011_0011,s3 = 8'b0010_0010,s4 = 8'b0110_0110,s5 = 8'b0111_0111,s6 = 8'b0101_0101,s7 = 8'b0100_0100,s8 = 8'b1100_1100,s9 = 8'b1101_1101,s10 = 8'b1111_1111,s11 = 8'b1110_1110,s12 = 8'b1010_1010,s13 = 8'b1011_1011,s14 = 8'b1001_1001,s15 = 8'b1000_1000,ss0 = 8'b0000_0001,ss1 = 8'b0001_0011,ss2 = 8'b0011_0010,ss3 = 8'b0010_0110,ss4 = 8'b0110_0111,ss5 = 8'b0111_0101,ss6 = 8'b0101_0100,ss7 = 8'b0100_1100,ss8 = 8'b1100_1101,ss9 = 8'b1101_1111,ss10 = 8'b1111_1110,ss11 = 8'b1110_1010,ss12 = 8'b1010_1011,ss13 = 8'b1011_1001,ss14 = 8'b1001_1000,ss15 = 8'b1000_0000;reg [7:0] s,nx_s;//state,next_statereg the_count_is_crazy;always@(posedge clk or negedge rst_n)beginif(rst_n == 0)s <= s0;elses <= nx_s;endalways@(*)begincase(s)s0:nx_s = ss0;ss0:nx_s = s1;s1:nx_s = ss1;ss1:nx_s = s2;s2:nx_s = ss2;ss2:nx_s = s3;s3:nx_s = ss3;ss3:nx_s = s4;s4:nx_s = ss4;ss4:nx_s = s5;s5:nx_s = ss5;ss5:nx_s = s6;s6:nx_s = ss6;ss6:nx_s = s7;s7:nx_s = ss7;ss7:nx_s = s8;s8:nx_s = ss8;ss8:nx_s = s9;s9:nx_s = ss9;ss9:nx_s = s10;s10:nx_s = ss10;ss10:nx_s = s11;s11:nx_s = ss11;ss11:nx_s = s12;s12:nx_s = ss12;ss12:nx_s = s13;s13:nx_s = ss13;ss13:nx_s = s14;s14:nx_s = ss14;ss14:nx_s = s15;s15:nx_s = ss15;ss15:nx_s = s0;endcaseendassign gray_out = s[7:4];
endmodule