Vector0

构建一个具有一个3位输入的电路,然后输出相同的矢量,并将其分成三个独立的1位输出。将输出连接到输入向量的位置 0、位置 1 等。o0,o1在图中,旁边带有数字的刻度线表示矢量(或“总线”)的宽度,而不是为矢量中的每个位绘制单独的线。

Vector0.png

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];
    assign o1 = vec[1];
    assign o2 = vec[2];
  
endmodule

![]()

仿真图片:


Vectors in more detail

构建一个组合电路,将输入半字(16 位,[15:0])拆分为较低的 [7:0] 和高部 [15:8] 字节。

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];
endmodule

仿真图片:


Vector part seledt

可以将 32 位向量视为包含 4 个字节(位 [31:24]、[23:16] 等)。构建一个电路,该电路将反转 4 字节字的字节顺序。

AaaaaaaaBbbbbbbbCcccccccDddddddd => DdddddddCcccccccBbbbbbbbAaaaaaaa

当一段数据的字节序需要交换时,例如在小端x86系统和许多Internet协议中使用的大端格式之间,通常使用此操作。

module top_module( 
    input [31:0] in,
    output [31:0] out );
    assign out[31:24] = in[7:0];
    assign out[23:16] = in[15:8];
    assign out[15:8] = in[23:16];
    assign out[7:0] = in[31:24];
endmodule


Biwise operators

构建一个具有两个 3 位输入的电路,用于计算两个向量的按位或、两个向量的逻辑或以及两个向量的逆 (NOT)。b的非给out_not[5:3],a的非给out_not[2:0]。

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|b;
    assign out_or_logical = a||b;
    assign out_not[2:0] = ~a;
    assign out_not[5:3] = ~b;

endmodule


Four-input gates

构建一个具有四个输入的组合电路in[3:0],有3个输出:

  • out_and:4 输入与门的输出。
  • out_or:4 输入或门的输出。
  • out_xor:4 输入异或门的输出。
//solution 1
module top_module( 
    input [3:0] in,
    output out_and,
    output out_or,
    output out_xor
);
  
    assign out_and = in[0]&in[1]&in[2]&in[3];
    assign out_or = in[0]|in[1]|in[2]|in[3];
    assign out_xor = in[0]^in[1]^in[2]^in[3];

endmodule

//solution 2
module top_module( 
    input [3:0] in,
    output out_and,
    output out_or,
    output out_xor
);
  
    assign out_and = ∈//reduction operator
    assign out_or = |in;
    assign out_xor = ^in;

endmodule


Vector concatenation operator

部分选择用于选择向量的部分。连接运算符{a,b,c}用于通过将向量的较小部分连接在一起来创建更大的向量。

{3'b111, 3'b000} => 6'b111000
{1'b1, 1'b0, 3'b101} => 5'b10101
{4'ha, 4'd10} => 8'b10101010 // 4'ha 和 4'd10 都是二进制的 4'b1010
连接需要知道每个组件的宽度(或者你怎么知道结果的长度?)。因此,{1, 2, 3}是非法的,并导致错误消息:unsized constants are not allowed in concatenations。

练习:给定几个输入向量,将它们连接在一起,然后将它们分成几个输出向量。有六个 5 位输入向量:a、b、c、d、e 和 f,总共 30 位输入。有四个 8 位输出向量:w、x、y 和 z,用于 32 位输出。输出应该是输入向量的串联,后跟两个1位:

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,2'b11};
    // assign { ... } = { ... };

endmodule


Vector reversal 1

给定一个 8 位输入向量 [7:0],反转其位顺序。

  • assign out [7:0] = in[0:7]; 不起作用,因为 Verilog 不允许翻转矢量位顺序。
  • 连接运算符可以节省一些编码,允许 1 个分配语句而不是 8 个。
//solution 1
module top_module (
    input [7:0] in,
    output [7:0] out
);

    assign {out[0],out[1],out[2],out[3],out[4],out[5],out[6],out[7]} = in;

endmodule

//solution 2
module top_module (
    input [7:0] in,
    output [7:0] out
);

    always @(*) begin
        for (int i=0; i<8; i++)    // int is a SystemVerilog type. Use integer for pure Verilog.
            out[i] = in[8-i-1];
    end

endmodule

//solution 3
module top_module (
    input [7:0] in,
    output [7:0] out
);

    generate
        genvar i;
        for (i=0; i<8; i = i+1) begin: my_block_name
            assign out[i] = in[8-i-1];
        end
    endgenerate

endmodule


Replication operator

构建一个将 8 位数字符号扩展为 32 位的电路。这需要连接 24 个符号位副本(即复制位 [7] 24 次),然后是 8 位数字本身。

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

More replication

给定五个 1 位信号(a、b、c、d 和 e),计算 25 位输出向量中的所有 25 个成对的一位比较。如果被比较的两位相等,则输出应为 1。

如图所示,使用复制和连接运算符可以更轻松地完成此操作。

  • 顶部向量是每个输入的 5 次重复的串联
  • 底部向量是 5 个输入的串联的 5 次重复
module top_module (
    input a, b, c, d, e,
    output [24:0] out
);

    wire [24:0] top, bottom;
    assign top    = { {5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}} };
    assign bottom = {5{a,b,c,d,e}};
    assign out = ~top ^ bottom;    // Bitwise XNOR

    // This could be done on one line:
    // assign out = ~{ {5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}} } ^ {5{a,b,c,d,e}};

endmodule
最后修改:2023 年 06 月 01 日
如果觉得我的文章对你有用,请随意赞赏