题解 | #格雷码计数器#

格雷码计数器

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

纯纯的逆天:
1:还是需要clk_half ,可能题目本意是格雷码转二进制再转格雷码。反正没说的很清楚。
解法3:题解 | #格雷码计数器#_牛客博客 (nowcoder.net) 状态机解决,第四位计数,高四位是格雷码输出。
问题2:我把clk_half 当做时钟触发cnt 计数,失败了。波形图不对。

格雷码的产生。
举例3位元的产生步骤:(22条消息) 格雷码基础和生成的几种方法_Franklin的博客-CSDN博客_格雷码生成
方法1:

产生的基本规律原则和标准做法

假设产生3位元的格雷码,原始值位 000
第一步:改变最右边的位元值: 001
第二步:改变右起第一个为1的位元的左边位元: 011

重复1:
第三步:改变最右边的位元值: 010
第四步:改变右起第一个为1的位元的左边位元: 110

重复2:
第五步:改变最右边的位元值: 111
第六步:改变右起第一个为1的位元的左边位元: 101

重复3:
第七步:改变最右边的位元值: 100 #已经走了(2^n) - 1  = 7步,完成所有码字的产生。

方法2:通过二进制和格雷码的转码规律生成:

2.3 镜像排列生成格雷码(对称法)

上面这个列表,分别给出位元为1,2,3的三组格雷码,其中灰色的部分是镜像分割线,黑色的格雷码码字和蓝色的格雷码码字是针对镜像分割线对称的



`timescale 1ns/1ns

module gray_counter(
   input   clk,
   input   rst_n,

   output  reg [3:0] gray_out
);
    reg [3:0] cnt;
    reg clk_half;
    
    always @(posedge clk, negedge rst_n) begin
        if (~rst_n) begin
            clk_half <= 1'b0;
        end
        else begin
            clk_half <= clk_half + 4'b1;
        end
    end
    
    always @(posedge clk, negedge rst_n) begin
        if (~rst_n) begin
            cnt <= 4'b0;
        end
        else begin
            cnt <= clk_half ? cnt + 4'b1 : cnt;
        end
    end
    
    
//     reg [3:0] i;
//     always @(posedge clk, negedge rst_n) begin
//         if (~rst_n) begin
//             gray_out <= 4'b0;
//         end
//         else begin
// //             for()
//             gray_out <= (cnt >> 1) ^ cnt;
//         end
//     end
    always @(*) begin
        if (~rst_n) begin
            gray_out <= 4'b0;
        end
        else begin
//             for()
            gray_out <= (cnt >> 1) ^ cnt;
        end
    end
endmodule



全部评论

相关推荐

球Offer上岸👑:可能是大环境太差了 太卷了 学历也很重要 hc也不是很多 所以很难
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客企业服务