HDLBits刷题Day02

这篇博客详细介绍了Verilog中数组和向量的使用,包括声明、部分选择、位运算、连接操作、反转及重复等。通过示例展示了如何在Verilog中进行位级操作,如按位与、或、异或,并讨论了四输入门的实现。此外,还探讨了生成块和循环在Verilog中的应用。

10. Vector0

数组类似C语言

type [upper:lower] vector_name
wire [99:0] my_vector;      // Declare a 100-element vector 
assign out = my_vector[10]; // Part-select one bit out of the vector 
//声明多个变量
wire [7:0] x,y;  //y 也被声明为位宽为 8 的向量
//也可以这样赋值
assign {o2, o1, o0} = vec;
module top_module ( 
   input wire [2:0] vec,
   output wire [2:0] outv,
   output wire o2,
   output wire o1,
   output wire o0  ); // Module body starts after module declaration
   assign outv=vec;
   assign o0=vec[0],o1=vec[1],o2=vec[2];
  
endmodule

片选多个 bit,该语法在 C 语言中不存在,但类似 Python 中的切片语法。

list[start:stop]
assign w = vec[1:0];

11.Vector1–Vector in more detail

//声明方法
wire [7:0] w;         // 8-bit wire
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.

比特顺序(endianness)
A[7:0]和A[0:7]不一样;这两个都是合法的,但必须前后保持一致;
变量隐式声明
Verilog对于未声明而直接使用的信号,综合器会主动将其声明为 1 bit wire 型信号,这可能会不够用;
隐式声明多出现在拷贝IP核时

`default_nettype none
//添加该宏定义可以关闭综合器自动添加,
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.
//在数组之前添加一个维度,代表着数组分块的长度;
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,和之前声明的不一样
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.

分割数组高低位

`default_nettype none     // Disable implicit nets. Reduces some types of bugs.
module top_module( 
    input wire [15:0] in,
    output wire [7:0] out_hi,
    output wire [7:0] out_lo );
    assign out_hi=in [15:8];
    assign out_lo=in [7:0];
    //assign {out_hi, out_lo} = in;这样更简单

endmodule

12.Vector–Vector PartSelect

每四个逆置数组

module top_module( 
//注意方向 ,数组的高低位;
    input [31:0] in,
    output [31:0] out );
    assign out[7:0]=in[31:24];
    assign out[15:8]=in[23:16];
    assign out[23:16]=in[15:8];    
    assign out[31:24]=in[7:0];
//assign out = {in[7-:8],in[15-:8],in[23-:8],in[31-:8]};
endmodule

13.Vectorgates–Bitwise operators

&:按位与;
&&:任何类型的输入都会被视作布尔值,零->假,非零->真,将布尔值进行逻辑比较后,输出一个 1 比特的结果。

module top_module( 
    input [2:0] a,
    input [2:0] b,
    output [2:0] out_or_bitwise,
    output out_or_logical,
    output [5:0] out_not
);
    assign out_or_bitwise=a[2:0]|b[2:0];
    // assign out_or_bitwise = a | b;
    //可以直接用“|”
    assign out_or_logical=a||b;
    assign out_not[2:0]=~a[2:0],out_not[5:3]=~b[2:0];
    //out_not[2:0] = ~a;out_not[5:3]=~b;
    //可以直接取反;
endmodule

注意高低位即可;

14.Four-input gates

Build a combinational circuit with four inputs, in[3:0].
There are 3 outputs:
out_and: output of a 4-input AND gate.
out_or: output of a 4-input OR gate.
out_xor: output of a 4-input XOR gate.
与门,或门,同或门;

module top_module( 
    input [3:0] in,
    output out_and,
    output out_or,
    output out_xor
);
    assign out_and=& in[3-:4];
    assign out_or=| in[3-:4];
    assign out_xor=^ in[3-:4];
    //a[b-:c]  c是长度;
    
    //assign out_and = & in;
    //assign out_or  = | in;
    //assign out_xor = ^ in;

endmodule

15.Vector3–

{3’b111, 3’b000} => 6’b111000
{1’b1, 1’b0, 3’b101} => 5’b10101
{4’ha, 4’d10} => 8’b10101010 // 4’ha and 4’d10 are both 4’b1010 in binary
Concatenation(连接):上述操作可以类似看作是一个并的操作;
Tips:必须知道长度,才能进行该操作;
assign左右都可以使用连接

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.

和c语言的数组类似,不足时自动补零;

连接操作符的基本语法:
使用 { } 将较小的向量括起来,每个 { } 内的向量使用逗号作为间隔。

module top_module (
    input [4:0] a, b, c, d, e, f,
    output [7:0] w, x, y, z );//

    assign {w,x,y,z}= {a,b,c,d,e,f,1'b1,1'b1};

endmodule

按照上面的去写报错;

Warning (13024): Output pins are stuck at VCC or GND
This warning says that an output pin never changes (is "stuck").
This can sometimes indicate a bug if the output pin shouldn't be a constant.
If this pin is not supposed to be constant, check for bugs that cause the value being assigned to never change (e.g., assign a = x & ~x;)

只是提醒某些值没有变化,可能有bug;
(啊,好人性的系统,不过我王某人一辈子都不会有bug!!!)

16.Vector–reverse

Solution 1–for循环

integer i;                     //提前定义 integer(整型) 变量
always @(*) begin	
     for (i=0; i<8; i++)	  //Use integer for pure Verilog. SystemVerilog才有int
	     out[i] = in[8-i-1];
end

创建一个组合逻辑 always 块;for 循环描述了电路的行为,而不是电路的结构,因此,for 循环必须置于比如 always 块这样的过程块中。(描述电路行为)
事实上,在逻辑合成器(瞎翻译的类似硬件的吧)会去生成电路;仿真器里只会执行循环;
真正的硬件电路不存在循环

Solution 2–使用 generate 生成块

generate
	genvar i;     //在生成块中的 for 循环中不能像前例一样使用 integer 作为循环变量,而是必须使用 genvar 变量
	for (i=0; i<8; i = i+1) begin: my_block_name
		assign out[i] = in[8-i-1];
	end
endgenerate

生成块可以动态的生成Verilog代码。
综合的来讲,for循环是在重复执行同一条语句;生成块则是将这些重复的语句挨个生成出来并执行;

17.Vector4–连接重复(replication operator)

Examples:

{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.
module top_module (
   input [7:0] in,
   output [31:0] out );//
   assign out={{24{in[7]}},in};
   // assign out = { replicate-sign-bit , the-input };

endmodule

{24{in[7]}}:其中的大括号一个都不能少;

18.Vector5

module top_module (
    input a, b, c, d, e,
    output [24:0] out );
    
    assign out=~{{5{a}},{5{b}},{5{c}},{5{d}},{5{e}}}^{5{a,b,c,d,e}};


    // The output is XNOR of two vectors created by 
    // concatenating and replicating the five inputs.
    // assign out = ~{ ... } ^ { ... };

endmodu

{{5{a}},{5{b}},{5{c}},{5{d}},{5{e}}}:每一层都要有括号;

19.Module

进入到模块的概念,

  1. 模块之间的调用只需要知道,输入输出端口即可
  2. 一般推荐一个 .v 文件中只写一个模块
  3. 模块中不能定义其他模块

实例化端口两种方法:

  1. 按端口顺序
    mod_a instance1 ( wa, wb, wc )
    将mod_a实例化成名为instance1的模块并且该模块的端口wa, wb,wc与mod_a定义时的端口顺序一致;

  2. 按端口名称
    mod_a instance2 ( .out(wc), .in1(wa), .in2(wb) );
    按照名称分别对应

模块例化的基本语法 :模块名 实例名(定义连接 port 的信号);

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值