最近跟着老师学习Verilog,做了中科大的练习题,将答案记录一下
Q1 输出1
题目描述
编写 Verilog 代码,使电路输出信号1
输入格式
无输入
输出格式
输出1,位宽为1
示例波形
代码
module top_module(
output out
);
// Write your code here
wire out;
assign out =1;
endmodule
Q2 输出0
题目描述
编写 Verilog 代码,使电路输出信号0
输入格式
无输入
输出格式
输出0,位宽为1
示例波形
代码
module top_module(
output out
);
// Write your code here
assign out=0;
endmodule
Q3 wire
wire
题目描述
wire 是 Verilog 的关键字,用于表征信号类型的,其含义是线网。wire 可理解为物理连线,但又有所不同,因为 Verilog 中的 wire 是有方向的。例如设计一模块,模块名命名为 top_module,输入信号名为 in,输出信号名为 out,使 in 与 out 直连,如下图所示:
请使用 assign 语句将代码补充完整,使其实现上述电路图的功能。
输入格式 任意
输出格式 与输入完全相同
示例波形
代码
module top_module(
input in, output out
);
// Write your code here
assign out = in;
endmodule
Q4 多个端口的模块
题目描述 wire是Verilog的关键字,用于表征信号类型的,其含义是线网,wire可理解为物理连线,但又有所不同,因为verilog中的wire是有方向的,例如设计一模块,模块名命名为top_module,输入信号名为in,输出信号名为out,使in与out直连,如下图所示:
请使用assign语句将代码补充完整,使其实现上述电路图的功能
输入格式 1 1 1 输出格式 1 1 1 1 示例波形
代码
module top_module(
input a,b,c,
output w,x,y,z );
// 请用户在下方编辑代码
assign w=a,x=b,y=b,z=c;
//用户编辑到此为止
endmodule
Q5 非门
题目描述 创建一个名为top_module的Verilog模块,实现非门的功能
输入格式 无 输出格式 无 示例波形
代码
module top_module( input in, output out );
// 请用户在下方编辑代码
assign out=~in;
//用户编辑到此为止
endmodule
Q6 与门
题目描述 创建一个Verilog模块,实现与门的逻辑功能,如下图所示:
输入格式 1bit a, 1bit b 输出格式 1bit out, 为 a and b 的结果 示例波形
代码
module top_module(
input a,
input b,
output out );
// 请用户在下方编辑代码
assign out=a&b;
//用户编辑到此为止
endmodule
Q7 或非门
题目描述 创建一个Verilog模块,实现或非门的逻辑功能,如下图所示:
输入格式 输入a,b均为1位 输出格式 输出out也为1位 示例波形
代码
module top_module(
input a,
input b,
output out );
// 请用户在下方编辑代码
assign out=~(a|b);
//用户编辑到此为止
endmodule
Q8 同或门
题目描述 创建一个Verilog模块,实现同或门的逻辑功能,对于两输入同或门来说,输入相同时输出1,输入不同时输出0,正好与异或门相反,如下图所示:
输入格式 1位的a和b 输出格式 1位的out 示例波形
代码
module top_module(
input a,
input b,
output out );
// 请用户在下方编辑代码
assign out=~(a^b);
//用户编辑到此为止
endmodule
Q9 线网型中间信号
题目描述 之前的verilog模块结构都比较简单,输出信号可直接用输入信号的逻辑表达式表示出来,模块功能稍微复杂时,一般都会用到中间信号,以下图为例,输入信号in经过两个非门后输出到out端口,为了在verilog模块中表示两个非门中间的这跟信号,需要将其定义为线网型(wire)信号,此处我们命名为not_in。
上述模块的verilog代码为:
请根据上述示例,完成下图中电路所对应的Verilog模块
输入格式 四个线网型变量a、b、c、d 输出格式 两个线网型变量out、out_n 示例波形
代码
module top_module(
input a,
input b,
input c,
input d,
output out,
output out_n
);
// 请用户在下方编辑代码
wire e,f,g;
assign e=a&b;
assign f=c&d;
assign out=e|f;
assign out_n=~out;
//用户编辑到此为止
endmodule
Q10 向量
题目描述
Hint: 向量是为了编写、阅读代码方便,将一组相关的信号用一个向量名称统一命名的方式。例如:
wire [7:0] w;
声明了一个8bit位宽的向量信号w,实际上代表的是8个1bit的wire型信号。 注意向量信号的声明是将位宽信息放在信号名之前,这与C语言不太一样。我们可以将向量信号中的一位或多位单独拿来使用。例如:
wire out;
wire [3:0] out_4;
wire [99:0] my_vector;
// 声明一个100bit的向量my_vector
assign out = my_vector[11] & my_vector[10];
// 选择其中两位信号进行运算
assign out_4 = my_vector[23:20];
// 选择其中4bit信号
任务目标: 创建一verilog模块,具有一个3bit位宽的输入向量信号,然后将其输出到3bit位宽的输出向量信号,同时再分别输出到3个1bit位宽的输出信号,如下图所示:
输入格式 1个3bit位宽的向量信号vec 输出格式 1个与输入vec保持一致的3bit位宽向量信号outv;
3个1bit位宽信号o0, o1, o2,分别对应输入信号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 o2=vec[2];
assign o1=vec[1];
assign o0=vec[0];
// 用户编辑到此为止
endmodule
Q11 向量_续 1
题目描述 创建一 Verilog 模块,将 16bit 输入信号 in 分成两个 8bit 的信号 out_hi、out_lo,然后输出,如下图所示:
输入格式 输入信号 in, 位宽 16bit,类型为 wire。 输出格式 输出信号 out_hi,位宽 8bit,为输入信号的高 8 位。
输出信号 out_lo,位宽 8bit,为输入信号的低 8 位。 示例波形
略
代码
`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
);
// Write your code here
assign out_hi=in[15:8];
assign out_lo=in[7:0];
endmodule
Q12 向量_续2
题目描述 一个32bit的向量信号包含有4个字节(bit[31:24]、bit[23:16]等),创建一个电路,用以调整4个字节的顺序,该电路经常用于在不同大小端系统之间进行数据交互: AaaaaaaaBbbbbbbbCcccccccDddddddd => DdddddddCcccccccBbbbbbbbAaaaaaaa 提示:part-select操作即可以用于赋值语句的左侧也可用于右侧。
输入格式 1个 32bit 位宽的向量信号 in 输出格式 1个 32bit 位宽的向量信号 out 示例波形
略
代码
module top_module(
input [31:0] in,
output [31:0] out
);
// assign out[31:24] = ...;
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
Q13 位操作
题目描述 创建一个电路,包含两个 3bit 的输入信号 a 和 b,分别对 ab 进行按位或、逻辑或操作,以及将 ab 拼接成 6bit 信号后进行按位取反,如下图所示:
输入格式 a = 3'b101
b = 3'b000 输出格式 按位或:3'b101
逻辑或:1
拼接ab后再按位取反:6'b111010 示例波形
代码
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
);
// Write your code here
assign out_or_bitwise=a|b;
assign out_or_logical=a||b;
assign out_not=~{b,a};
endmodule
Q14 位操作
题目描述 创建一个组合逻辑电路,包含4bit输入(in[3:0]),和3个输出,分别为: -out_and:四输入与门的输出信号 -out_or:四输入或门的输出信号 -out_xor:四输出异或门的输出信号 电路结构如下图所示:
输入格式 0 0 0 0 输出格式 0 0 0 示例波形
代码
module top_module(
input [3:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and=∈
assign out_or=|in;
assign out_xor=^in;
endmodule
Q15 向量拼接
题目描述 part_selection用于选择向量信号中的一部分,而向量拼接算子{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 and 4'd10 are both 4'b1010 in binary
向量拼接时,每个信号都需要有明确的位宽,这样拼接后的信号才会有明确的位宽。例如,{1,2,3}就是非法的,因为无法确定各信号的位宽,语法检查时会报错。 向量拼接算子既可以用于赋值语句的左侧,也可用于右侧,如下所示:
input [15:0] in;
output [23:0] out;
assign {out[7:0], out[15:8]} = in;
assign out[15:0] = {in[7:0], in[15:8]};
assign out = {in[7:0], in[15:8]};
创建Verilog电路,将6个5bit位宽的输入信号,以及2bit的常量信号2’b11拼接成32bit的向量信号,并将其拆成4个8bit的信号,分别赋值给4个输出信号,如下图所示:
输入格式 6个5位宽的输入信号a,b,c,d,e,f输出格式 4个8位宽的信号w,x,y,z 示例波形
略
代码
module top_module (
input [4:0] a, b, c, d, e, f,
output [7:0] w, x, y, z );
// assign { ... } = { ... };
assign w={a,b[4:2]};
assign x={b[1:0],c,d[4]};
assign y={d[3:0],e[4:1]};
assign z={e[0],f,2'b11};
endmodule
Q16 向量翻转
题目描述 创建verilog电路,将8bit的输入信号按bit翻转,并输出到输出端口,如下图所示:
输入格式 8 bit in 输出格式 8 bit out, 为in的向量翻转 示例波形
代码
module top_module(
input [7:0] in,
output [7:0] out
);
assign out={in[0],in[1],in[2],in[3],in[4],in[5],in[6],in[7]};
endmodule
Q17 复制算子
题目描述复制算子是拼接算子的一种特殊情况,如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]}},in};
endmodule
Q18 复制算子_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 = ~{{5{a}},{5{b}},{5{c}},{5{d}},{5{e}}} ^ { 5{a,b,c,d,e}};
endmodule
Q19 模块例化
题目描述 通过前面一系列的练习,用户应当已经熟悉单个模块电路的设计了。对于功能上更复杂的电路模块,一般都是由若干子模块以及附加的功能电路构成的。
在模块实例化过程中,被例化模块的端口信号是最重要的,用户甚至可以不知道模块的内部结构。上图展示了一个非常简单的包含有子模块电路的电路结构,在此电路中,创建模块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
模块的实例化为例,可以在上层模块中使用以下语句:
其中inst_name1是mod_a模块的实例化名称,可以由用户自定义,通过这种例化方式,便实现了端口对应:wa↔in1
, wb↔in2
, wc↔out
。 基于端口名称的实例化如下所示
本教程推荐用户使用基于端口名称的例化方式,因为这种方式编写的代码可读性更强。 试创建一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
Q20 基于端口位置的实例化
题目描述 创建一verilog电路,实现对模块mod_a基于端口位置的实例化,如下图所示:
其中mod_a模块的代码提供为:
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
Q21 基于端口名称的实例化
题目描述 创建一 verilog 电路,实现对模块 mod_a 基于端口名称的实例化,如下图所示:
其中mod_a模块的代码为:
module mod_a (
output out1,
output out2,
input in1,
input in2,
input in3,
input in4
);
assign out1 = in1 & in2 & in3 & in4; //这只是一个简单的示例
assign out2 = in1 | in2 | in3 | in4; //这只是一个简单的示例
endmodule
输入格式 输入信号 a, b, c, d,位宽 1bit。 输出格式 输出信号 out1, out2,位宽 1bit。 示例波形
代码
module mod_a (
output out1 ,
output out2 ,
input in1 ,
input in2 ,
input in3 ,
input 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
);
//Write your code here
mod_a mod_a (
.out1(out1) ,
.out2(out2) ,
.in1(a) ,
.in2(b) ,
.in3(c) ,
.in4(d)
);
endmodule
Q22 多个模块的例化
题目描述 创建一个Verilog模块,实现或非门的逻辑功能,如下图所示:
输入格式 输入a,b均为1位 输出格式 输出out也为1位 示例波形
代码
module my_dff(input clk,input d,output reg q);
always@(posedge clk)
q <= d;
endmodule
module top_module ( input clk, input d, output q );
// Write your code here
wire q1,q2;
my_dff my_dff1(.clk(clk),.d(d),.q(q1));
my_dff my_dff2(.clk(clk),.d(q1),.q(q2));
my_dff my_dff3(.clk(clk),.d(q2),.q(q));
endmodule
Q23 模块与向量信号
题目描述对于给定模块 my_dff8,其代码如下所示:
试创建一 Verilog 模块,对 my_dff8 模块例化 3 次,并串行连接,构成一个 8bit 位宽长度为 3 的移位寄存器,同时可以通过选择信号选择输出结果,如下图所示:
代码
module my_dff8(
input clk,
input [7:0] d,
output reg [7:0] q
);
always@(posedge clk)
q <= d;
endmodule
module top_module(
input clk,
input [7:0] d,
input [1:0] sel,
output reg [7:0] q
);
// Write your code here
wire[7:0] q1,q2,q3;
my_dff8 my_dff8_q1(
.clk(clk),
.d(d),
.q(q1)
);
my_dff8 my_dff8_q2(
.clk(clk),
.d(q1),
.q(q2)
);
my_dff8 my_dff8_q3(
.clk(clk),
.d(q2),
.q(q3)
);
always@(*)
begin
case(sel)
0: q=d;
1:q=q1;
2:q=q2;
3:q=q3;
endcase
end
endmodule