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

问题28 Always blocks(combinational) (Alwaysblock1)

由于数字电路是由用导线连接的逻辑门组成的,因此任何电路都可以表示为模块和赋值语句的某种组合。然而,有时这并不是描述电路的最方便的方式。Procedures (of which always blocks are one example) provide an alternative syntax for describing circuits.


对于综合硬件,两种类型的 always 块是相关的:


Combinational: always @(*)

Clocked: always @(posedge clk)

组合always blocks 等同于赋值语句,因此总有一种方法可以双向表达组合电路。选择使用哪个主要是哪个语法更方便的问题。程序块内部代码的语法与外部代码不同。 程序块有更丰富的语句集(例如,if-then、case),不能包含连续赋值,但也引入了许多新的非直观的出错方式。(Procedural continuous assignments 确实存在,但与连续赋值有些不同,并且不可综合。)


例如,assign和combinational always块描述相同的电路。两者都创建了相同的组合逻辑块。无论何时任何输入(右侧)改变值,两者都将重新计算输出。

assign out1 = a & b | c ^ d;
always @(*) out2 = a & b | c ^ d;
• 1
• 2

对于combinational always块,始终使用 (*)的敏感度列表。显式列出信号容易出错(如果您错过了一个信号),在硬件合成中会被忽略。如果显式指定灵敏度列表并错过信号,则合成硬件的行为仍将如同指定了(*),但模拟将与硬件的行为不匹配。(在 SystemVerilog 中,使用 always_comb。)关于 wire 与 reg 的注意事项:assign 语句的左侧必须是 net 类型(例如,wire),而过程赋值(在 always block中)的左侧必须是变量类型(例如,reg)

A bit of practice

使用 assign 语句和组合 always block构建 AND 门。

// synthesis verilog_input_version verilog_2001
module top_module(
    input a, 
    input b,
    output wire out_assign,
    output reg out_alwaysblock
);
    assign out_assign = a & b;
    always @(*) begin
        out_alwaysblock = a & b;
    end
endmodule


问题29: Always blocks(clocked) (Alwaysblock2)

对于硬件综合,有两种相关的 always block

组合型: always @(*)

时序型: always @(posedge clk)

Clocked always blocks总是创建了一个组合逻辑块,而且还会在组合逻辑块的输出处创建一组触发器(或“寄存器”)。不是立即可见逻辑块的输出,而是仅在下一个(posedge clk)之后立即可见输出。


Blocking vs. Non-Blocking Assignment

Verilog 中有三种类型的赋值:

Continuous assignments (assign x = y;). Can only be used when not inside a procedure (“always block”).

Procedural blocking assignment: (x = y;). Can only be used inside a procedure.

Procedural non-blocking assignment: (x <= y;). Can only be used inside a procedure.

在combinational always block,使用blocking assignments. 在clocked always block中,使用non-blocking assignments.

A bit of practice

以三种方式构建XOR gate,使用assign statement、combinational always block和clocked always block。请注意,the clocked always block产生的电路与其他两个不同:有一个触发器,因此输出被延迟

// synthesis verilog_input_version verilog_2001
module top_module(
    input clk,
    input a,
    input b,
    output wire out_assign,
    output reg out_always_comb,
    output reg out_always_ff   );
    assign out_assign = a ^ b;
    always@(*)begin
        out_always_comb = a ^ b;
    end
    always@(posedge clk)begin
        out_always_ff <= a ^ b;
    end
endmodule


问题30: If statement(Always if)

if 语句通常创建一个 21 多路复用器,如果条件为真则选择一个输入,如果条件为假则选择另一个输入。

always @(*) begin
    if (condition) begin
        out = x;
    end
    else begin
        out = y;
    end
end

这等效于使用带有条件运算符的连续赋值:

assign out = (condition) ? x : y;
• 1

但是,程序 if 语句提供了一种新的出错方式。仅当总是为 out 分配一个值时,该电路才是组合电路。

A bit of practice

构建一个在 ab 之间进行选择的 21 多路复用器。如果 sel_b1sel_b2 都为真,则选择 b。否则,选择a。做同样的事情两次,一次使用分配语句,一次使用过程 if 语句。

// synthesis verilog_input_version verilog_2001
module top_module(
    input a,
    input b,
    input sel_b1,
    input sel_b2,
    output wire out_assign,
    output reg out_always   ); 
    assign out_assign = (sel_b2 & sel_b1) ? b : a;
    always@(*)begin
        if(sel_b2 & sel_b1)begin
            out_always = b;
        end
        else begin
            out_always = a;
        end
    end
endmodule


问题31If statement latches(Always if2)

常见的错误来源:如何避免锁存。

设计电路时,首先要从电路方面考虑:

I want this logic gate

I want a combinational blob of logic that has these inputs and produces these outputs

I want a combinational blob of logic followed by a set of flip-flops

你不能做的是先写代码,然后希望它生成一个合适的电路。

If (cpu_overheated) then shut_off_computer = 1;

If (~arrived) then keep_driving = ~gas_tank_empty;

语法正确的代码不一定会产生合理的电路(组合逻辑 + 触发器)。通常的原因是:“在您指定的情况以外的情况下会发生什么?”。 Verilog 的回答是:保持输出不变。


这种“保持输出不变”的行为意味着需要记住当前状态,从而产生一个锁存器。组合逻辑(例如逻辑门)不能记住任何状态。在所有条件下,组合电路必须为所有输出分配一个值。这通常意味着您总是需要 else 子句或分配给输出的默认值。

// synthesis verilog_input_version verilog_2001
module top_module (
    input      cpu_overheated,
    output reg shut_off_computer,
    input      arrived,
    input      gas_tank_empty,
    output reg keep_driving  ); //
    always @(*) begin
        if (cpu_overheated) begin
           shut_off_computer  = 1;
        end
        else begin
            shut_off_computer = 0;
        end
    end
    always @(*) begin
        if (~arrived) begin
           keep_driving = ~gas_tank_empty;
        end
        else begin
           keep_driving = 0;
        end
    end
endmodule

问题32: Case statement(Always case)

Verilog 中的 case 语句几乎等同于将一个表达式与其他表达式进行比较的 if-elseif-else 序列。它的语法和功能不同于 C 中的 switch 语句。

always @(*) begin     // This is a combinational circuit
    case (in)
      1'b1: begin 
               out = 1'b1;  // begin-end if >1 statement
            end
      1'b0: out = 1'b0;
      default: out = 1'bx;
    endcase
end

case 语句以 case 开头,每个case item以冒号结尾。没有switch。

每个案例项只能执行一个语句。这使得 C 中使用的break变得不必要。但这意味着,如果您需要多个语句,则必须使用 begin ... end。

允许重复(和部分重叠)案例项目。使用第一个匹配的。 C语言不允许重复的案例项目。

A bit of practice

如果有大量 casecase 语句比 if 语句更方便。因此,在本练习中,创建一个 61 多路复用器。当 sel05 之间时,选择对应的数据输入。否则,输出 0。数据输入和输出均为 4 位宽。

// synthesis verilog_input_version verilog_2001
module top_module ( 
    input [2:0] sel, 
    input [3:0] data0,
    input [3:0] data1,
    input [3:0] data2,
    input [3:0] data3,
    input [3:0] data4,
    input [3:0] data5,
    output reg [3:0] out   );//
    always@(*) begin  // This is a combinational circuit
        case(sel)
            3'b000: begin
                  out = data0;
                   end
            3'b001: begin
                  out = data1;
                   end
            3'b010: begin
                  out = data2;
                   end
            3'b011: begin
                  out = data3;
                   end
            3'b100: begin
                  out = data4;
                   end
            3'b101: begin
                  out = data5;
                   end
            default: begin
                  out = 4'b 0000;
                end
        endcase
    end
endmodule
// synthesis verilog_input_version verilog_2001
module top_module ( 
    input [2:0] sel, 
    input [3:0] data0,
    input [3:0] data1,
    input [3:0] data2,
    input [3:0] data3,
    input [3:0] data4,
    input [3:0] data5,
    output reg [3:0] out   );//
    always@(*) begin  // This is a combinational circuit
        out = 4'b 0000;
        case(sel)
            3'b000: begin
                  out = data0;
                   end
            3'b001: begin
                  out = data1;
                   end
            3'b010: begin
                  out = data2;
                   end
            3'b011: begin
                  out = data3;
                   end
            3'b100: begin
                  out = data4;
                   end
            3'b101: begin
                  out = data5;
                   end
        endcase
    end
endmodule

相关文章
|
3月前
|
人工智能 算法 ice
【2024美赛】D题(中英文):五大湖水资源问题Problem Problem D: Great Lakes Water Problem
【2024美赛】D题(中英文):五大湖水资源问题Problem Problem D: Great Lakes Water Problem
55 1
HDLBits: 在线学习Verilog(Problem 120-126)
HDLBits: 在线学习Verilog(Problem 120-126)
86 0
|
机器学习/深度学习 人工智能 算法
【读书笔记】Algorithms for Decision Making(1)
我自己的粗浅看法:机器学习要不是拟合逼近(经常提及的machine learning),要不就是决策过程(reinforcement learning),这本书主要讲述后者的前世今生。
308 0
【读书笔记】Algorithms for Decision Making(1)
|
Python
【读书笔记】Algorithms for Decision Making(2)
理性决策需要对不确定性和目标进行推理。不确定性源于预测未来事件能力的实际及理论限制。为了实现其目标,一个强有力的决策系统必须考虑到当前世界状况和未来事件中的各种不确定性来源。
109 0
【读书笔记】Algorithms for Decision Making(2)
|
算法 关系型数据库 数据建模
【读书笔记】Algorithms for Decision Making(4)
本部分讨论从数据学习或拟合模型参数的问题,进一步讨论了从数据中学习模型结构的方法,最后对决策理论进行了简单的概述。
【读书笔记】Algorithms for Decision Making(4)
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
268 0
HDLBits(2)——Procedures(下)
|
机器学习/深度学习 算法 数据挖掘
Re17:读论文 Challenges for Information Extraction from Dialogue in Criminal Law
Re17:读论文 Challenges for Information Extraction from Dialogue in Criminal Law
Re17:读论文 Challenges for Information Extraction from Dialogue in Criminal Law
|
算法 机器人
【读书笔记】Algorithms for Decision Making(10)
在这一部分将不确定性扩展到状态。具体讲,接收到的观测值与状态只有概率关系,而不是精确地观察状态。此类问题可以建模为部分可观察的马尔可夫决策过程(POMDP),但POMDP很难以最佳方式解决所有问题,因而需要引入更多的近似策略。
154 0
|
机器学习/深度学习
AtCoder Beginner Contest 218 F - Blocked Roads (最短路径还原 思维)
AtCoder Beginner Contest 218 F - Blocked Roads (最短路径还原 思维)
88 0