Advertisement

HDLBits 答案汇总(持续更新)

阅读量:

目录

Vectors

Vectors in more detals​​

Vector part select

Bitewise operators

four input gates

Vector concatenation operations

Replication operators

More replication

Module

Three modules

Modules and vectors

Add1

Adder 2

Carry-select adder(Module cseladd)

Adder subtractor(Module addsub)



Vectors

Vectors in more detals

Vector part select

hint: 赋值的左右两侧都可以对矢量进行部分选择。

Bitewise operators

Hint:

按位布尔运算符:&,|,^,~

逻辑布尔运算符:&&,||,!

four input gates

hint: 矢量的按位布尔运算在矢量前加上布尔运算符即可。

Vector concatenation operations

Hint: 位宽必须进行标注,11必须标为 2'd11,才可以。

分号;必须是英文状态下的,而不是;中文状态下的。

复制代码
 module top_module (

    
     input [4:0] a, b, c, d, e, f,
    
     output [7:0] w, x, y, z );
    
  
    
  
    
     assign {w[7:0]} = {a[4:0], b[4:2]};
    
     assign {x[7:0]} = {b[1:0], c[4:0], d[4]};
    
     assign {y[7:0]} = {d[3:0], e[4:1]};
    
     assign {z[7:0]} = {e[0], f[4:0], 2'b11};
    
   11. //second way
    
   13. //assign {w, x, y, z} = {a, b, c, d, e, f, 2'b11};
    
  
    
 endmodule

Replication operators

Hint: sign bit 符号位进行扩展保留,其他位保持不变即可。

复制代码
 module top_module (

    
     input [7:0] in,
    
     output [31:0] out );
    
     
    
     assign out = {{24{in[7]}}, in [7:0]};
    
  
    
 //second way
    
  
    
 //assign out = {{24{in[7]}}, in};
    
  
    
 endmodule

More replication

hint:结合矢量的按位布尔运算,连接符{},复制操作,3种操作复合。

复制代码
 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}};
    
  
    
 endmodule

Module

hint:

复制代码
 module top_module ( input a, input b, output out );

    
     
    
     mod_a instance1 (a, b, out);   //根据mod_a模块的输入输出声明(需要提前声明,题中给了)从左向右对应来写top_module的输入输出口。
    
  
    
 //second way
    
  
    
 //mod_a instance1 (.in1(a), .in2(b), .out(out));
    
  
    
 endmodule

Connecting ports by name

复制代码
 module top_module (

    
     input a,
    
     input b,
    
     input c,
    
     input d,
    
     output out1,
    
     output out2
    
 );
    
     
    
     mod_a instance1 (.out1(out1), .out2(out2), .in1(a), .in2(b), .in3(c), .in4(d));//括号外是实例化模块的接口,括号内是外界的接口
    
  
    
 //second way
    
  
    
 //mod_a(.out1(out1), .out2(out2), .in1(a), .in2(b), .in3(c), .in4(d));
    
  
    
 //mod_a不进行命名也可以,不要忘了英文的句号.   而不是中文的
    
  
    
 endmodule

Three modules

solution 1

复制代码
 module top_module ( input clk, input d, output q );

    
     
    
     wire w1;
    
     wire w2;
    
     my_dff dff1(clk,d,w1);//括号内都是实例化模块之外的接口,实例化模块的接口顺序已经定义
    
  
    
                                    //好,一一对应即可。
    
     my_dff dff2(clk,w1,w2);
    
     my_dff dff3(clk,w2,q);
    
  
    
 endmodule

solution 2:

复制代码
 module top_module (

    
     input clk,
    
     input d,
    
     output q
    
 );
    
  
    
     wire a, b;    // Create two wires. I called them a and b.
    
  
    
     // Create three instances of my_dff, with three different instance names (d1, d2, and d3).
    
     // Connect ports by position: ( input clk, input d, output q)
    
     my_dff d1 ( clk, d, a );
    
     my_dff d2 ( clk, a, b );
    
     my_dff d3 ( clk, b, q );
    
  
    
 endmodule

Modules and vectors

solution:

复制代码
 module top_module (

    
     input clk,
    
     input [7:0] d,
    
     input [1:0] sel,
    
     output [7:0] q
    
 );
    
     wire [7:0] w1;
    
     wire [7:0] w2;
    
     wire [7:0] w3;
    
     
    
     my_dff8 d1(clk,d,w1);
    
     my_dff8 d2(clk,w1,w2);
    
     my_dff8 d3(clk,w2,w3);
    
     
    
     always @(*) begin
    
     case(sel)
    
         2'b00:
    
             q=d;
    
         2'b01:
    
             q=w1;                
    
         2'b10:
    
             q=w2;                
    
         2'b11:
    
             q=w3;                
    
     endcase
    
     end
    
  
    
 endmodule

Add1

solution 1

复制代码
 module top_module(

    
     input [31:0] a,
    
     input [31:0] b,
    
     output [31:0] sum
    
 );
    
     wire w1;
    
     
    
     add16 add1(a[15:0],b[15:0],1'b0,sum[15:0],w1);//注意是a[15:0],而不是[15:0] a。
    
     add16 add2(a[31:16],b[31:16],w1,sum[31:16], );//不连接的接口直接空下就行,其前面的,可
    
   11.                                                                                 //以不加。
    
   13. endmodule

solution 2

复制代码
 module top_module(

    
     input [31:0] a,
    
     input [31:0] b,
    
     output [31:0] sum
    
 );
    
     wire w1;
    
     
    
     add16 add1(
    
     .a(a[15:0]),
    
     .b(b[15:0]),
    
     .cin(1'b0),
    
     .sum(sum[15:0]),
    
     .cout(w1)
    
     );
    
     add16 add2(
    
     .a(a[31:16]),
    
     .b(b[31:16]),
    
     .cin(w1),
    
     .sum(sum[31:16]),
    
     .cout( )
    
     );
    
   23. endmodule

solution 3

复制代码
 module top_module(

    
     input [31:0] a,
    
     input [31:0] b,
    
     output [31:0] sum
    
 );
    
     
    
     wire w1,w2;
    
     wire [15:0] low_out;
    
     wire [15:0] high_out;
    
     
    
     add16 add1(a[15:0],b[15:0],0,low_out,w1);//这个地方的0,可以直接写0,或者写成1'b0
    
     add16 add2(a[31:16],b[31:16],w1,high_out,w2);
    
     
    
     assign sum = {high_out, low_out};
    
    
    
   17. endmodule

solution 4

将solution3中改为按名称连接即可。

Adder 2

复制代码
 module top_module (

    
     input [31:0] a,
    
     input [31:0] b,
    
     output [31:0] sum
    
 );
    
     wire w1;//分号;必须使用英文状态下的,不然可能会在其他地方报错
    
     
    
     add16 block1 (a[15:0],b[15:0],1'b0,sum[15:0],w1);
    
     add16 block2 (a[31:16],b[31:16],w1,sum[31:16]);  
    
   11. endmodule
    
   13. module add1 ( input a, input b, input cin,   output sum, output cout );
    
     assign {cout,sum} = a + b + cin;//不需要再定义a,b,c等,在add16中已经对应过了,只需要对sum和cout定义即可,可以参考向量的拼接内容
    
   16. endmodule

Carry-select adder(Module cseladd)

提前加法进位器,用资源换速度

将一个额外的新建第一个16位全加法电路加入系统中,并分别完成进位为0和1的情况下的运算操作;然后将第一个全加法电路的 cout 输出端与一个2选1 多路复用电路相连,并利用该复用电路的功能选择并输出对应第二个全加法电路在特定进位条件下的运算结果。
这样一来,在运算过程中实现了对多个全加法电路运算过程的有效同步。

solution1

按位置

复制代码
 module top_module(

    
     input [31:0] a,
    
     input [31:0] b,
    
     output [31:0] sum
    
 );
    
     wire [15:0] highout0;
    
     wire [15:0] highout1;
    
     wire cout;
    
     
    
     add16 low(a[15:0],b[15:0],0,sum[15:0],cout);
    
     add16 high0(a[31:16],b[31:16],0,highout0);
    
     add16 high1(a[31:16],b[31:16],1,highout1);
    
     
    
     assign sum[31:16]=cout? highout1:highout0;//数据选择器的描述
    
  
    
 endmodule

solution 2

按名称

复制代码
 module top_module(

    
     input [31:0] a,
    
     input [31:0] b,
    
     output [31:0] sum
    
 );
    
     
    
     wire cout_out;
    
     wire [15:0] high0;
    
     wire [15:0] high1;//在声明线网时,必须进行位宽的设置,否则默认为 1 bit
    
     
    
     add16 low(
    
     .a(a[15:0]),
    
     .b(b[15:0]),
    
     .cin(1'b0),
    
     .sum(sum[15:0]),
    
     .cout(cout_out )
    
     );
    
     add16 high_out0(
    
     .a(a[31:16]),
    
     .b(b[31:16]),
    
     .cin(1'b0),
    
     .sum(high0),
    
     .cout( )       //没有用的管脚可以直接不声明
    
     );
    
     add16 high_out1(
    
     .a(a[31:16]),
    
     .b(b[31:16]),
    
     .cin(1'b1),
    
     .sum(high1),
    
     .out( )
    
     );
    
     
    
     assign sum[31:16] = cout_out?high1:high0;//注意high1和high0之间用的:连接
    
   35. endmodule

Adder subtractor(Module addsub)

题目:

关键点:采用32位宽的XOR门,在sub信号为1的情况下翻转b输入。
问题:如何用Verilog实现这一功能?
解答:因为Verilog中没有直接的逻辑异或操作符(即只能执行两位的信息处理),所以必须利用按位布尔运算符^来进行操作。
具体来说,在将32位输入b与32位sub信号进行异或操作后(即计算b ^ sub),每次只能处理两位信息并执行相应的布尔操作。
因此当sub信号为1时(即{32{sub}}),计算结果等价于对b逐位取反(即~b)。
而加1的操作则由cin端子与sub端子相连来控制;当sub信号为0时(即{32{0}}),异或操作不会对b产生任何影响。

solution1 按位置

复制代码
 module top_module(

    
     input [31:0] a,
    
     input [31:0] b,
    
     input sub,
    
     output [31:0] sum
    
 );
    
     wire [31:0] b_out;
    
     wire cout_out;
    
     
    
     assign b_out = b ^ {32{sub}};
    
     
    
     add16 low(a[15:0],b_out[15:0],sub,sum[15:0],cout_out);
    
     add16 high(a[31:16],b_out[31:16],cout_out,sum[31:16]);
    
  
    
 endmodule

solution2 按名称

复制代码
 module top_module(

    
     input [31:0] a,
    
     input [31:0] b,
    
     input sub,
    
     output [31:0] sum
    
 );
    
     wire [31:0] b_out;//将b_out直接声明为32bit数据,在下面时可以用[31:16],[15:0]区别
    
     wire cout_out;
    
     
    
     assign b_out = b ^ {32{sub}};
    
     
    
     add16 low(
    
     .a(a[15:0]),
    
     .b(b_out[15:0]),
    
     .cin(sub),
    
     .sum(sum[15:0]),
    
     .cout(cout_out)
    
     );
    
     add16 high(
    
     .a(a[31:16]),
    
     .b(b_out[31:16]),
    
     .cin(cout_out),
    
     .sum(sum[31:16])
    
     );
    
  
    
 endmodule

全部评论 (0)

还没有任何评论哟~