HDLBits(2)——Procedures(下)

简介: HDLBits——Procedures问题28 Always blocks(combinational) (Alwaysblock1)A bit of practice问题29: Always blocks(clocked) (Alwaysblock2)Blocking vs. Non-Blocking AssignmentA bit of practice问题30: If statement(Always if)A bit of practice问题31If statement latches(Always if2)常见的错误来源:如何避免锁存。问题32: Case st


问题33: Priority encoder(Always case2)

优先级编码器是一种组合电路,当给定输入位向量时,输出向量中第一个 1 位的位置。例如,给定输入 8'b100100008 位优先级编码器将输出 3'd4,因为 bit[4] 是第一个高位。

构建一个 4 位优先级编码器。对于这个问题,如果没有输入位为高(即输入为零),则输出零。请注意,一个 4 位数字有 16 种可能的组合

// synthesis verilog_input_version verilog_2001
module top_module (
    input [3:0] in,
    output reg [1:0] pos  );
    always@(*)begin
        casez(in)
            4'bzzz1: begin
                pos = 2'b00;
            end
            4'bzz1z: begin
                pos = 2'b01;
            end
            4'bz1zz: begin
                pos = 2'b10;
            end
            4'b1zzz: begin
                pos = 2'b11;
            end
            default: begin
                pos = 2'b00;
            end
*斜体样式*        endcase
    end
endmodule


问题34: Priority encoder with casez(Always casez)

为 8 位输入构建优先级编码器。给定一个 8 位向量,输出应报告向量中的第一位为 1。如果输入向量没有高位,则报告零。例如,输入 8'b10010000 应该输出 3'd4,因为 bit[4] 是第一个高位

从之前的练习 (always_case2) 来看,case 语句中有 256 个案例。如果 case 语句中的 case 项支持 don’t-care 位,我们可以减少这个(减少到 9 个 case

例如,这将实现上一个练习中的 4 输入优先级编码器:

always @(*) begin
    casez (in[3:0])
        4'bzzz1: out = 0;   // in[3:1] can be anything
        4'bzz1z: out = 1;
        4'bz1zz: out = 2;
        4'b1zzz: out = 3;
        default: out = 0;
    endcase
end

case 语句的行为就好像每个项目都是按顺序检查的(实际上是一个很大的组合逻辑函数)。请注意某些输入(例如 4'b1111)如何匹配多个案例项目。选择第一个匹配项(因此 4’b1111 匹配第一项,out = 0,但不匹配后面的任何一项)。


明确指定优先级行为而不是依赖于案例项目的顺序可能不太容易出错。例如,如果某些 case 项被重新排序,以下内容的行为仍然相同,因为任何位模式最多只能匹配一个 case 项:

// synthesis verilog_input_version verilog_2001
module top_module (
    input [7:0] in,
    output reg [2:0] pos  );
    always@(*) begin
        casez (in)
            8'b zzzzzzz1:begin
                pos = 3'b 000;
            end
            8'b zzzz_zz1z: begin
                pos = 3'b 001;
            end
            8'b zzzz_z1zz: begin
                pos = 3'b 010;
            end
            8'b zzzz_1zzz: begin
                pos = 3'b 011;
            end
            8'b zzz1_zzzz: begin
                pos = 3'b 100;
            end
            8'b zz1z_zzzz: begin
                pos = 3'b 101;
            end
            8'b z1zz_zzzz: begin
                pos = 3'b 110;
            end
            8'b 1zzz_zzzz: begin
                pos = 3'b 111;
            end
            default: begin
                pos = 3'b 000;
            end
        endcase
    end
endmodule


问题35: Avoiding latches(Always nolatches)

假设您正在构建一个电路来处理来自游戏的 PS/2 键盘的扫描码。鉴于收到的扫描码的最后两个字节,您需要指出是否已按下键盘上的箭头键之一。这涉及到一个相当简单的映射,它可以实现为具有四个案例的案例语句(或 if-elseif)。


您的电路有一个 16 位输入和四个输出。构建识别这四个扫描码并断言正确输出的电路。


为避免创建锁存器,必须在所有可能的条件下为所有输出分配一个值(另请参见 always_if2)。仅仅有一个默认情况是不够的。您必须为所有四种情况和默认情况下的所有四个输出分配一个值。这可能涉及大量不必要的输入。解决此问题的一种简单方法是在 case 语句之前为输出分配一个“默认值”:

always @(*) begin
    up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
    case (scancode)
        ... // Set to 1 as necessary.
    endcase
end

这种代码风格确保在所有可能的情况下为输出分配一个值(0),除非 case 语句覆盖了分配。这也意味着 default:case 项变得不必要了。

提醒:逻辑合成器生成一个组合电路,其行为与代码描述的内容等效。硬件不会按顺序“执行”代码行。

// synthesis verilog_input_version verilog_2001
module top_module (
    input [15:0] scancode,
    output reg left,
    output reg down,
    output reg right,
    output reg up  ); 
    always@(*) begin
        up = 1'b0;
        down = 1'b0;
        left = 1'b0;
        right = 1'b0;
        case(scancode)
            16'he06b:begin
                left = 1'b1;
            end
            16'he072:begin
                down = 1'b1;
            end
            16'he074:begin
                right = 1'b1;
            end
            16'he075:begin
                up = 1'b1;
            end
        endcase
    end
endmodule



此种方法,首先进行了赋值,这样是不会产生锁存,是一种较好的思维的方式,笔者可以尝试采用此方法进行对上面的问题进行实验验证。

相关文章
|
2月前
|
算法 数据挖掘 数据处理
文献解读-Sentieon DNAscope LongRead – A highly Accurate, Fast, and Efficient Pipeline for Germline Variant Calling from PacBio HiFi reads
PacBio® HiFi 测序是第一种提供经济、高精度长读数测序的技术,其平均读数长度超过 10kb,平均碱基准确率达到 99.8% 。在该研究中,研究者介绍了一种准确、高效的 DNAscope LongRead 管道,用于从 PacBio® HiFi 读数中调用胚系变异。DNAscope LongRead 是对 Sentieon 的 DNAscope 工具的修改和扩展,该工具曾获美国食品药品管理局(FDA)精密变异调用奖。
27 2
文献解读-Sentieon DNAscope LongRead – A highly Accurate, Fast, and Efficient Pipeline for Germline Variant Calling from PacBio HiFi reads
HDLBits: 在线学习Verilog(Problem 120-126)
HDLBits: 在线学习Verilog(Problem 120-126)
118 1
|
Python
【读书笔记】Algorithms for Decision Making(2)
理性决策需要对不确定性和目标进行推理。不确定性源于预测未来事件能力的实际及理论限制。为了实现其目标,一个强有力的决策系统必须考虑到当前世界状况和未来事件中的各种不确定性来源。
119 0
【读书笔记】Algorithms for Decision Making(2)
|
C语言
HDLBits(2)——Procedures(上)
HDLBits——Procedures 问题28 Always blocks(combinational) (Alwaysblock1) A bit of practice 问题29: Always blocks(clocked) (Alwaysblock2) Blocking vs. Non-Blocking Assignment A bit of practice 问题30: If statement(Always if) A bit of practice 问题31If statement latches(Always if2) 常见的错误来源:如何避免锁存。 问题32: Case st
192 0
HDLBits(2)——Procedures(上)
|
算法 机器人
【读书笔记】Algorithms for Decision Making(10)
在这一部分将不确定性扩展到状态。具体讲,接收到的观测值与状态只有概率关系,而不是精确地观察状态。此类问题可以建模为部分可观察的马尔可夫决策过程(POMDP),但POMDP很难以最佳方式解决所有问题,因而需要引入更多的近似策略。
168 0
|
vr&ar
【读书笔记】Algorithms for Decision Making(5)
此前讲述了在某个时间点做一个单一的决定的问题,但许多重要的问题需要做出一系列的决定。序列环境中的最佳决策需要对未来行动和观察序列进行推理。
119 0
|
机器学习/深度学习
AtCoder Beginner Contest 218 F - Blocked Roads (最短路径还原 思维)
AtCoder Beginner Contest 218 F - Blocked Roads (最短路径还原 思维)
99 0
|
安全
HDU-1039,Easier Done Than Said?(字符串处理)
HDU-1039,Easier Done Than Said?(字符串处理)
|
安全 开发工具 git
Merging 和 Rebasing 的大比拼
Merging 和 Rebasing 的大比拼
167 0
Merging 和 Rebasing 的大比拼