16 向量翻转
题目描述
创建verilog电路,将8bit的输入信号按bit翻转,并输出到输出端口,如下图所示:
输入格式
8 bit in
输出格式
8 bit out, 为in的向量翻转
module top_module(
input [7:0] in,
output [7:0] out);
assign out[7] = in[0];
assign out[6] = in[1];
assign out[5] = in[2];
assign out[4] = in[3];
assign out[3] = in[4];
assign out[2] = in[5];
assign out[1] = in[6];
assign out[0] = in[7];
endmodule
17 复制算子
题目描述
复制算子是拼接算子的一种特殊情况,如a={b,b,b,b,b,b}便可以写成a={6{b}}的形式。复制算子的格式为:{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
创建一verilog电路,将一个8bit位宽的输入信号进行符号位扩展,并通过32bit的输出端口输出,如下图所示
输入格式
8位in信号
输出格式
32位out信号
module top_module (
input [7:0] in,
output [31:0] out );//
// assign out = { replicate-sign-bit , the-input };
assign out = {{24{in[7:7]}},in};
endmodule
18 复制算子_2
题目描述
创建一verilog电路,包含5个1bit输入,使所有输入两两进行同或(两bit相同时输出1,不同时输出0),并将结果通过25bit的向量信号输出,如下图所示:
使用复制算子实现该电路,可以大大减少代码量,提高编码效率。
输入格式
1位的a,b,c,d,e
输出格式
25位的out
module top_module (
input a, b, c, d, e,
output [24:0] out );//
// The output is XNOR of two vectors created by
// concatenating and replicating the five inputs.
// assign out = ~{ ... } ^ { ... };
assign out[24:20] = ~ {{5{a}} ^ {a,b,c,d,e}};
assign out[19:15] = ~ {{5{b}} ^ {a,b,c,d,e}};
assign out[14:10] = ~ {{5{c}} ^ {a,b,c,d,e}};
assign out[9:5] = ~ {{5{d}} ^ {a,b,c,d,e}};
assign out[4:0] = ~ {{5{e}} ^ {a,b,c,d,e}};
endmodule
19 模块例化
题目描述
通过前面一系列的练习,用户应当已经熟悉单个模块电路的设计了。对于功能上更复杂的电路模块,一般都是由若干子模块以及附加的功能电路构成的。
在模块实例化过程中,被例化模块的端口信号是最重要的,用户甚至可以不知道模块的内部结构。上图展示了一个非常简单的包含有子模块电路的电路结构,在此电路中,创建模块mod_a的一个实例化,并将该实例化模块的三个端口(in1
,in2
,out
)与顶层电路的三个端口(a
,b
,out
)直接连接,其中mod_a
模块的代码如下:
module mod_a ( input in1, input in2, output out );
// Module body
assign out = in1 & in2; //这只是一个简单的示例
endmodule
模块实例化一般有两种语法格式,分别称为基于端口名称的实例化和基于端口位置的实例化。
基于位置的实例化和C语言中的函数调用类似(只是语法上类似,实际上该例化会产生实际的硬件电路),以上述mod_a
模块的实例化为例,可以在上层模块中使用以下语句:
module top_module(input wa,input wb,output wc);
mod_a inst_name1(wa,wb,wc);
endmodule
其中inst_name1是mod_a模块的实例化名称,可以由用户自定义,通过这种例化方式,便实现了端口对应:wa↔in1
, wb↔in2
, wc↔out
。
基于端口名称的实例化如下所示
module top_module(input wa,input wb,output wc);
mod_a inst_name2(
.out (wc),
.in1 (wa),
.in2 (wb));
endmodule
本教程推荐用户使用基于端口名称的例化方式,因为这种方式编写的代码可读性更强。
试创建一verilog电路,并按照上图中所示实例化mod_a
模块(建议使用基于端口名称的方式实例化)。
Hint:
- 推荐使用基于端口名称的实例化方式
- 模块调用就像是一个树形的层次结构,不允许循环调用,如a调用b,b又调用a,也不允许模块调用自身,即模块c中又实例化模块c。
- 不允许在进程块(如always、initial等)或赋值语句(如assign语句)内进行模块实例化
- 模块的实例化名称可以自定义,如在同一模块中要对一个模块多次实例化,需要有不同的实例化名称。
输入格式
一位线网型变量a、b
输出格式
一位线网型变量out
module top_module(
input a,
input b,
output out
);
// 请用户在下方编辑代码
mod_a inst_name2(
.out (out),
.in1 (a),
.in2 (b));
//用户编辑到此为止
endmodule
module mod_a (
input in1,
input in2,
output out
);
assign out = in1 & in2;
endmodule
20基于端口位置的实例化
题目描述
创建一verilog电路,实现对模块mod_a基于端口位置的实例化,如下图所示:
其中mod_a模块的代码提供为:
module mod_a(
output out1, out2,
input in1,in2,in3,in4);
assign out1 = in1 & in2 & in3 & in4;
//这只是一个简单的示例
assign out2 = in1 | in2 | in3 | in4;
//这只是一个简单的示例
endmodule
Hint:
-实例化名称可以与模块名称相同
-实例化模块时,需要注意端口信号的位宽相匹配,本例中都是1bit,所以不存在问题
输入格式
4个1bit信号a, b, c, d
输出格式
经由模块mod_a输出的信号out1, out2
module mod_a(
output out1, out2,
input in1,in2,in3,in4);
assign out1 = in1 & in2 & in3 & in4; //这只是一个简单的示例
assign out2 = in1 | in2 | in3 | in4; //这只是一个简单的示例
endmodule
module top_module(
input a,
input b,
input c,
input d,
output out1,
output out2
);
// 请用户在下方编辑代码
mod_a inst_name2(
.out1 (out1),
.out2 (out2),
.in1 (a),
.in2 (b),
.in3 (c),
.in4 (d)
);
// 用户编辑到此为止
endmodule
这样也可以:
module mod_a(
output out1, out2,
input in1,in2,in3,in4);
assign out1 = in1 & in2 & in3 & in4; //这只是一个简单的示例
assign out2 = in1 | in2 | in3 | in4; //这只是一个简单的示例
endmodule
module top_module(
input a,
input b,
input c,
input d,
output out1,
output out2
);
// 请用户在下方编辑代码
mod_a inst_name1( out1, out2, a, b, c, d);
// 用户编辑到此为止
endmodule