首页 > 其他分享 >HDLBits-Verilog Practice-1-Getting started -> Circuits.Combinational Logic

HDLBits-Verilog Practice-1-Getting started -> Circuits.Combinational Logic

时间:2022-10-12 16:47:47浏览次数:89  
标签:wire Getting started always HDLBits input output assign out

注:建议使用 Ctrl+F 利用关键词、题号、题目名称 查阅本文内容

笔记内容

  1. 本文范围 Getting started -> Circuits.Combinational Logic

  2. 网页本身给出的语法点,和一些语法的使用思路

  3. 做题过程中的反思

  4. 参考HDLBits 中文导学 - 知乎

  5. 参考答案xiaop1/Verilog-Practice: HDLBits website practices & solutions

待归档内容

  • 组合逻辑 写进 always块 的 敏感列表

    • (在某次编译时候看到的warning)

      You used a signal in an always block but didn't add it to the sensitivity list. Just use always@(*) and let the compiler deal with it. Quartus will use the correct sensitivity list, but Modelsim and other simulators won't, leading to a mismatch between simulation and logic synthesis, which is incredibly hard to debug.

    • Alwaysblock1 - HDLBits 中相反的观点,For combinational always blocks, always use a sensitivity list of (*).Explicitly listing out the signals is error-prone (if you miss one), and is ignored for hardware synthesis. If you explicitly specify the sensitivity list and miss a signal, the synthesized hardware will still behave as though (*) was specified, but the simulation will not and not match the hardware's behaviour. (In SystemVerilog, use always_comb.)

  • 其它:

    • Vivado下试出来的几条 Verilog 综合的规则_Tiger-Li的博客-CSDN博客

      总体原则:操作要与输出信号相关,不相关的全部视为无用信号,综合成电路是被综合掉。

      1,always过程中 中间变量自己给自己赋值的操作,在综合出来的电路中会被忽略掉, 因为对电路的输出没有意义。

      2,输入信号赋值给中间变量, 但是没有跟输出相关,被综合掉。

      3,中间变量赋给常量值,在综合时会根据位值 直接连接对应位D触发器的set信号,使D触发器常量,而不会连接跟clk有关的D信号。

      4,语句的书写顺序与执行顺序无关,但是与综合顺序有关,如果发生冲突,例如两个信号同时连接到输出信号, 那么后面书写的语句会将前面书写的语句生成的电路覆盖掉。

      5,输入信号,中间结果赋给中间变量,只要这个中间变量最后与输出有关,就会在中间生成触发器来存储,这个就是写流水线的方法。


Getting started

编译工具 Quartus

仿真工具 ModelSim, 用于验证

Verilog Language

Basics

笔记

这一部分题重在体会 硬件描述语言 是如何描述硬件的,硬件有什么是可以描述的,需要见微知著。纯粹用高级语言的思路刷题当然很快,但是日后就会犯一些思维不同的隐蔽的错误。

T3,Wire

不像生活中物理意义上的导线,Verilog中的wire是有方向的。即,信息流从一边进(源也称为 driver)到另一边出(称为sink)。

Wire

T4,Wire4

assign 语句中的持续性”赋值”语句 的本质是连线/连接(connection),而不是高级语言中的拷贝赋值。

Unlike a programming language, assign statements ("continuous assignments") describe connections between things, not the action of copying a value from one thing to another.

T3 图中的绿色带箭头的线 表示wires之间的关系(connection),而不是wire本身。声明的黑色输入输出端口才是wire(除非端口被声明为reg类型。注:这个reg不是真的寄存器,只是一个verilog历史遗留的语法(syntax))。

T5,Notgate

verilog中,“!”表示逻辑求反,“~”表示按位求反。当对位宽为1的变量进行操作时,这两个操作符的作用是一样的,都是求反。当对位宽为2的变量a[1:0]进行操作时,这两个操作符的作用就不一样了:“!”表示 ~(a[0] | a[1]),只有当a的每一位都为0时,结果才为1,条件判断中 if(!a) 等价于 if(a == 0);“~”表示对每一位按位取反,只有当a的每一位都为1时,结果才为0。

注:与门、或门同理。

T6,Andgate

  1. As you might expect, a wire cannot have more than one driver (what is its logic level if there is?)

这里是硬件描述语言!所以 wires 不像C语言中的变量可以多次用不同的statement去“赋值”!一个wire若有多个驱动(driver),则会报错 Multiple Driver Nets

Multiple Driver Nets

注意到一个wire不能有多个driver不代表这个wire的输出是一个恒定不变的值。wire a 连线至 wire b 后,输入改变,输出也将改变,所以wire b的值是可以变的。

所以这题讲完上述,引入了与门!!!两个 input driver通过某种关系映射成一个去驱动output。

  1. and a wire that has no drivers will have an undefined value (often treated as 0 when synthesizing hardware).

此外,没有驱动的 wire 综合时一般置0.

T7,Norgate

  • net 是 wire 的正式称呼,中文常翻译为线网。

  • 组合电路,就是无记忆性的,没有隐藏状态

    combinational (i.e., memory-less, with no hidden state)

T9,Declaring Wires

  1. (In the future, you will encounter more types of signals and variables that are also declared the same way, but for now, we'll start with a signal of type wire).

新的 wire 需在使用前声明,新的 wire 可用来连接内部的模块——这点可在日后多加体会它与高级程序语言中的变量的不同之处。

Wiredecl1

  1. Notice how wires are driven by exactly one source (output of a gate), but can feed multiple inputs.

这在 T6 的第一点中也有谈到过

Wiredecl2

注:这当然也可以不用许多中间wires来实现。

题目:step_one

显示的写出数据宽度1'和数据表示形式为二进制b是一个好习惯

assign one = 1'b1;

题目:wire4

对于下面的

assign w = a;
assign x = b;
assign y = b;
assign z = c;

如果确切知道每个信号的宽度,使用下面这个写法会更简介

assign {w,x,y,z} = {a,b,b,c};

Vectors

笔记

向量、级联、复制这三个工具一套组合拳!大杀器!

Vector5 - HDLBits

T11,12, Vector0, Vector1

Vectors are used to group related signals using one name to make it more convenient to manipulate. For example, wire [7:0] w; declares an 8-bit vector named w that is equivalent to having 8 separate wires.

引入 向量(vector) 概念,通过索引更便于操作变量。对比T12提到的 packed 和unpacked array

type [upper:lower] vector_name;

type 多为 wire 或 reg。

[upper:lower]

  • 为可变向量域(参考 2.3 Verilog 数据类型 | 菜鸟教程 );
  • upper >lower =>小端,upper <lower =>大端;两种声明方式都可以,但后续索引切片方式必须和声明方式一致:writing vec[1:2] when vec is declared wire [3:0] vec; is illegal.
  • 声明向量大小端方式的一致性很重要,否则会导致奇怪的bug。

声明向量(Declaration)示例

//T11
wire [99:0] my_vector;      // Declare a 100-element vector

//T12
reg  [4:1] x;         // 4-bit reg
output reg [0:0] y;   // 1-bit reg that is also an output port (this is still a vector)
input wire [3:-2] z;  // 6-bit wire input (negative ranges are allowed)
output [3:0] a;       // 4-bit output wire. Type is 'wire' unless specified otherwise.
wire [0:7] b;         // 8-bit wire where b[0] is the most-significant bit.

注:大小端看的是LSB(Least Significant Bit),小端(little-endian)要求LSB有lower index,大端(Big-endian)反之。

索引向量(Part-Select)示例

assign w = a;

使用向量名字访问整个向量。连线时,若左右选择的数据长度不匹配,会进行截断或者0扩展(是0扩展,而不是符号位扩展,因为在当前这个层次,我们没有 signed intunsigned int的概念,只有比特0和1)。

其它示例,

//T11
assign out = my_vector[10]; // Part-select one bit out of the vector

//T12
//Declaration
wire [7:0] w;         // 8-bit wire
reg  [4:1] x;         // 4-bit reg
input wire [3:-2] z;  // 6-bit wire input (negative ranges are allowed)
wire [0:7] b;         // 8-bit wire where b[0] is the most-significant bit.

//Part-Select
w[3:0]      // Only the lower 4 bits of w
x[1]        // The lowest bit of x
x[1:1]      // ...also the lowest bit of x
z[-1:-2]    // Two lowest bits of z
b[3:0]      // Illegal. Vector part-select must match the direction of the declaration.
b[0:3]      // The *upper* 4 bits of b.
assign w[3:0] = b[0:3];    // Assign upper 4 bits of b to lower 4 bits of w. w[3]=b[0], w[2]=b[1], etc.

隐式线网 Implicit nets

避免它的方式是使用指令(directive) `default_nettype none

未声明就使用(通过 assign 语句或与 module port 相连接)的符号默认为 1bit wire 类型,将和我们预期的向量类型不符,从而导致bug。

bug示例:

wire [2:0] a, c;   // Two vectors
assign a = 3'b101;  // a = 101
assign b = a;       // b =   1  implicitly-created wire
assign c = b;       // c = 001  <-- bug
my_module i1 (d,e); // d and e are implicitly one-bit wide if not declared.
                    // This could be a bug if the port was intended to be a vector.
Unpacked vs. Packed Arrays

You may have noticed that in declarations, the vector indices are written before the vector name. This declares the "packed" dimensions of the array, where the bits are "packed" together into a blob (this is relevant in a simulator, but not in hardware). The unpacked dimensions are declared after the name. They are generally used to declare memory arrays. Since ECE253 didn't cover memory arrays, we have not used packed arrays in this course. See http://www.asic-world.com/systemverilog/data_types10.html for more details.

reg \[7:0\] mem \[255:0\];   // 256 unpacked elements, each of which is a 8-bit packed vector of reg.
reg mem2 \[28:0\];         // 29 unpacked elements, each of which is a 1-bit reg.

注:packed array types cannot assigned to unpacked array types! 表明 wire [31:0]a; wire b[31:0]; 是两种东西,也就不能写 assign a=b;

T13,Vector2

考虑字节为单位的循环移位,常是因为 不同协议之间的大小端规定不同,需要转换。AaaaaaaaBbbbbbbbCcccccccDddddddd => DdddddddCcccccccBbbbbbbbAaaaaaaa

T16,Vector3

需要知道每个元素的位宽(否则无法知道结果的位宽),因此没有注明数据位宽的 {1,2,3} 是违法的。

级联将引发0扩展Line:5 所示,

input [15:0] in;
output [23:0] out;
assign {out[7:0], out[15:8]} = in;         // Swap two bytes. Right side and left side are both 16-bit vectors.
assign out[15:0] = {in[7:0], in[15:8]};    // This is the same thing.
assign out = {in[7:0], in[15:8]};       // This is different. The 16-bit vector on the right is extended to match the 24-bit vector on the left, so out[23:16] are zero. In the first two examples, out[23:16] are not assigned.

T18,Vector4

Replication vector,复制操作

语法:{num{vector}}

num 必须是常量;两对花括号都是必要的;

示例:

{5{1'b1}}           // 5'b11111 (or 5'd31 or 5'h1f)
{2{a,b,c}}          // The same as {a,b,c,a,b,c}
{3'd5, {2{3'd6}}}   // 9'b101_110_110. It's a concatenation of 101 with
                    // the second vector, which is two copies of 3'b110.

该操作常用来扩展最高位。(因为级联默认的是0扩展!)

题目:Vector1

第 n+1次 忘记写级联(concatenation)。

不简洁的写法

assign out_hi = in[15:8];
assign out_lo = in[7:0];

和简洁的写法

// Concatenation operator also works: 
assign {out_hi, out_lo} = in;

Modules: Hierarchy

笔记

T20,Module

复杂电路通过小模块等其它组件(assign语句和过程块)构成。这构成 层次结构(hierarchy),因为一个模块可以包括其它模块的实例化(可以一直嵌套,只要这些模块属于同一个项目——可以被编译器找到)。

实现不同模块的功能呆码不可以嵌套。

Module

实例化模块的两种方式:建议养成 通过名字实例化 的习惯。

  1. 通过位置,mod_a instance1 ( wa, wb, wc );

    优点:简洁;缺点:可扩展性差——一旦模块的端口列表顺序有调整,所有实例都得改。

  2. 通过名字 mod_a instance2 ( .out(wc), .in1(wa), .in2(wb) );

    优点:可扩展性强;缺点:冗长。

T24,Module shift8

多资源+串行+向量。(相较于 Mt2015 q4 那题,本题实际是存在门级电路延迟的)

(Essentially, sel selects how many cycles to delay the input, from zero to three clock cycles.)

Module_shift8

T26,module_fadd;T27,Module cseladd

放全加器的模块图,提醒自己,我们是硬件!硬件!硬件!

全加器的多种实现方式。这就是从数字逻辑到计算机组成与设计的一步。

T26

Module_fadd

T27

Module_cseladd

Procedures

笔记

T29,Alwaysblock1

  • For synthesizing hardware, two types of always blocks are relevant:

    • Combinational: always @(*)

    • Clocked: always @(posedge clk)

  • Combinational always blocks 总是等价于 assign 语句。所以哪种语法方便用哪种。

  • 过程块有更丰富的语法,不支持可综合的持续性赋值语法,也引入了更多写bug的方法

    标签:wire,Getting,started,always,HDLBits,input,output,assign,out
    From: https://www.cnblogs.com/quixotiiiiic/p/16784986.html

相关文章

  • HDLBits-Verilog Practice-2-Circuits.Sequential Logic -> Circuits.More Circuits
    注:建议使用Ctrl+F利用关键词、题号、题目名称查阅本文内容笔记内容本文范围Circuits.SequentialLogic->Circuits.MoreCircuits网页本身给出的语法点,和一些......
  • Compacting, Picking and Growing for Unforgetting Continual Learning论文阅读笔记
    摘要本文提出了一种简单有效的连续学习策略,利用了深度模型压缩、关键权重选择和渐进网络扩展的原则并进行整合。方法的优点:避免遗忘、允许模型扩展,同时可以通过之前的积......
  • Single Transaction Analysis (ST12) getting started
    货铺QQ群号:834508274heSingleTransactionAnalysiswasdeveloped topromotetheusageofABAPtraceinsideSAPSupport.ItintegratestheABAP-(SE30)andtheP......
  • 了解Pytorch|Get Started with PyTorch
    一个开源的机器学习框架,加速了从研究原型到生产部署的路径。!pipinstalltorch-ihttps://pypi.tuna.tsinghua.edu.cn/simpleimporttorchimportnumpyasnpBasics......
  • Get started with NuGet packages in Azure Artifacts
    GetstartedwithNuGetpackagesinAzureArtifactsDownloadNuGetpackages1.Getthefeed'ssourceURLFromwithinyourproject,selectArtifacts,andthen......
  • Go 学习(一) : Get started with Go
    安装gohttps://go.dev/doc/install安装以后命令行执行goversion然后随便创建一个文件,比如hello.gopackagemainimport"fmt"funcmain(){ fmt.Printl......
  • HDLbits - rotate 100 提问草稿
    提问:verilog在进行数值比较(使用==,===,>=,<=等比较运算符)时,如果有一个或两个运算符是未知的(比如x或z),会有怎样的行为?详细解释:我正在做HDLbits的这道题目(题目链接:http......
  • HDLBits(5) 9.1
    2Verilog语言2.2向量2.3.6加法器1实例化一个由两个16位加法器组合成的32位加法器moduletop_module(input[31:0]a,input[31:0]b,output[31:0]......
  • HDLBits答案——Circuits
    1CombinationalLogic1.1BasicGates1.1.1Exams/m2014q4hmoduletop_module(inputin,outputout); assignout=in;endmodule1.1.2Exams/m2014q......
  • HDLBits(二) 8.22
    2.Verilog语言2.1基础2.1.7声明导线创建一个中间信号,用于简化整个电路模块的逻辑表达语法:wirefoo;#foo为定义的wirename#wirew1,w2;  as......