Verilog语言——HDLBits刷题记录(三)
Modules:Hierarchy
文章目录
Modules
模块:模块是通过输入、输出来连接外部电路的一种电路结构;可以进行嵌套(模块里套模块),这时你根本不用管内部的代码,只需知道端口即可
例化模块端口的两种方法(通过名字或者位置)
1.通过位置例化,就是按照顺序来例化,一一对应,如果模块的端口顺序改变,连接函数instance1也要改变
2.通过名字例化,这时跟顺序无关,特别要注意的是端口前面的**“.”**
You may connect signals to the module by port name or port position. For extra practice, try both methods.
Connecting ports by position
You are given a module named mod_a that has 2 outputs and 4 inputs, in that order. You must connect the 6 ports by position to your top-level module's ports out1, out2, a, b, c, and d, in that order.
Connecting ports by name
You are given a module named mod_a that has 2 outputs and 4 inputs, in some order. You must connect the 6 ports by name to your top-level module's ports:
You are given the following module:
module mod_a ( output out1, output out2, input in1, input in2, input in3, input in4);
Three modules
You are given a module my_dff with two inputs and one output (that implements a D flip-flop). Instantiate three of them, then chain them together to make a shift register of length 3.
Modules and vectors
ou are given a module my_dff8 with two inputs and one output (that implements a set of 8 D flip-flops). Instantiate three of them, then chain them together to make a 8-bit wide shift register of length 3. In addition, create a 4-to-1 multiplexer (not provided) that chooses what to output depending on sel[1:0]: The value at the input d, after the first, after the second, or after the third D flip-flop. (Essentially, sel selects how many cycles to delay the input, from zero to three clock cycles.)
拓展:1.四选一选择器
这个模块是还没给出的,需要自己去写
// This is one way to make a 4-to-1 multiplexer
always @(*) // Combinational always block
case(sel)
2'h0: q = d;
2'h1: q = o1;
2'h2: q = o2;
2'h3: q = o3;
endcase //多个选择则通过case语句
2.向量的写法
my_dff8 instance1 (.clk(clk),.d(d),.q(a));
my_dff8 instance2 (.clk(clk),.d(d[7:0]),.q(a[7:0])); //这两者写法都是可以的,是等效的
3.packed array和unpacked array两者之间的区别
wire out[7:0]; //unpacked array
wire [7:0]out; // packed array
//两者的区别主要是维数的区别
4.wire不能连续的去定义
wire a,b,c; //在Verilog中是不能这样连续的去定义变量的
Adder 1
You are given a module add16 that performs a 16-bit addition. Instantiate two of them to create a 32-bit adder. One add16 module computes the lower 16 bits of the addition result, while the second add16 module computes the upper 16 bits of the result, after receiving the carry-out from the first adder.
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] sum1;
wire [15:0] sum2;
wire out_in;
wire out;
add16 instance1(a[15:0],b[15:0],1'b0,sum1[15:0],out_in);
add16 instance2(a[31:16],b[31:16],out_in,sum2[15:0],out);
assign sum[31:0]={sum2,sum1};
endmodule
注意:赋值语句中一定要有assign关键字,不然无法赋值,本人吃过这个亏
Adder 2
In this exercise, you will create a circuit with two levels of hierarchy. Your top_module will instantiate two copies of add16 (provided), each of which will instantiate 16 copies of add1 (which you must write). Thus, you must write two modules: top_module and add1.
Connect the add16 modules together as shown in the diagram below. The provided module add16 has the following declaration:
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
module add1 ( input a, input b, input cin, output sum, output cout );
Recall that a full adder computes the sum and carry-out of a+b+cin.
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire out_in;
add16 low (a[15:0],b[15:0],0,sum[15:0],out_in);
add16 high(a[31:16],b[31:16],out_in,sum[31:16]);
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
assign {cout,sum} = a + b + cin;
endmodule
PS:题目要理解对,本题目是要实现两个模块,一个是32位的,一个是1位的全加器,16位的加法器是已知的。
Carry-select adder
In this exercise, you are provided with the same module `add16` as the previous exercise, which adds two 16-bit numbers with carry-in and produces a carry-out and 16-bit sum. You must instantiate *three* of these to build the carry-select adder, using your own 16-bit 2-to-1 multiplexer.
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] high_sum;
wire [15:0] high_sum2;
wire cout;
add16 instance1(a[15:0],b[15:0],0,sum[15:0],cout);
add16 instance2(a[31:16],b[31:16],0,high_sum[15:0]);
add16 instance3(a[31:16],b[31:16],1,high_sum2[15:0]);
always @(*)
if(cout)
sum[31:16] =high_sum2[15:0];
else
sum[31:16] =high_sum[15:0];
endmodule
PS:进位加法器虽然构造简单,但是运算速度很慢,而改进后的加法器是高位和低位同时运行的,再搭载一个高速二选一选择器。
Adder-subtractor
An adder-subtractor can be built from an adder by optionally negating one of the inputs, which is equivalent to inverting the input then adding 1. The net result is a circuit that can do two operations: (a + b + 0) and (a + ~b + 1).
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire [31:0] input1;
wire out_in;
assign input1[31:0]={32{sub}}^b[31:0]; //input1表示的是b的补码,
add16 instance1(a[15:0],input1[15:0],sub,sum[15:0],out_in);
add16 instance2(a[31:16],input1[31:16],out_in,sum[31:16]);
endmodule
PS:补码可以用用原码的反码加一,同时也可以用异或门来实现。而且注意异或的符号是^,并且异或时要每一位都对应。