题解 | #格雷码计数器#

格雷码计数器

http://www.nowcoder.com/practice/311754bcd45d42eb8d981eeddbdf1e43

题解主体

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

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

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

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

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

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


全部评论
格雷码转二进制不合理,always模块里面用阻塞赋值
2 回复 分享
发布于 2022-08-12 18:02
各位佬们,请问一下为啥二进制转格雷码那块里又把值赋给了gray_wire,这是不是说明这个东西是个闭环
点赞 回复 分享
发布于 2024-09-26 22:33 江苏
怎么看着和脱裤子放屁一样
点赞 回复 分享
发布于 2023-11-21 16:06 北京
这种风格代码,面试直接刷
点赞 回复 分享
发布于 2023-06-15 16:12 四川
`timescale 1ns/1ns module gray_counter( input clk, input rst_n, output reg [3:0] gray_out ); //题目意思是输入格雷码输出格雷码,中间用二进制来计数 //格雷码计数器,分为三部分进行设计:格雷码转二进制、加法器、二进制转格雷码 //1.格雷码转二进制——修改原题解的时序逻辑使用阻塞赋值的奇怪写法 reg [3:0] bin_out; wire [3:0] gray_wire; wire [3:0] bin_wire; genvar i; generate for (i=0; i<=3; i=i+1) begin: gray2bin if (i == 3) assign bin_wire[i] = gray_wire[i]; else assign bin_wire[i] = gray_wire[i] ^ bin_wire[i+1]; end endgenerate always @(posedge clk or negedge rst_n) begin if(!rst_n) begin bin_out <= 4'b0; end else begin bin_out <= bin_wire; end end //2.二进制加一 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 //3.二进制转格雷码 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
点赞 回复 分享
发布于 2023-04-11 15:45 广东
好像都用非阻塞会报错,请问有佬能解释一下吗,谢谢
点赞 回复 分享
发布于 2022-12-17 17:16 陕西
我觉得同一个always块中同时用阻塞和非阻塞赋值不太好,都用非阻塞直接写全就行了
点赞 回复 分享
发布于 2022-11-23 13:49 上海
请问二进制为啥要+1呀?是为了防止溢出吗?
点赞 回复 分享
发布于 2022-08-24 09:49 安徽

相关推荐

rbjjj:太杂了吧,同学,项目似乎都没深度,都是api调度耶,分层架构思想没有体现出来了,前端没有前端优化前端工程化体现,后端微服务以及分层架构没体现以及数据安全也没体现,核心再改改,注重于计算机网络,工程化,底层原理吧
点赞 评论 收藏
分享
评论
5
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务