Verilog RTL 代码设计新手上路(学生实验4--11)

学生实验
把加法器的输出信号改成4比特位宽,编译,波形仿真。观察输出结果,说出输出和输入的对应关系。
把加法器的输入信号改成8比特位宽,编译,波形仿真。观察加法器的输出延迟,和4比特输入位宽的情况对比,你有什么结论,为什么?
4比特位宽实验代码如下:
module unadd4_4(
IN1,
IN2,
OUT);
input [3:0] IN1,IN2;
output [3:0] OUT;
reg [3:0] OUT;
always @ (IN1 or IN2) begin
OUT = IN1 + IN2;
end
endmodule
仿真结果如下:
在这里插入图片描述
8比特位宽实验代码如下:
module unadd8_5(
IN1,
IN2,
OUT);
input [7:0] IN1,IN2;
output [4:0] OUT;
reg[4:0] OUT;
always @ (IN1 or IN2) begin
OUT = IN1 + IN2;
end
endmodule
仿真结果如下:
在这里插入图片描述
学生实验

把加法器的输出信号改成4比特位宽,编译,波形仿真。观察输出结果,观察输出结果在什么时候是正确的?。 把加法器的输入信号改成8比特位宽,编译,波形仿真。观察加法器的输出延迟,和4比特输入位宽的情况对比,你有什么结论,为什么?

4比特位宽实验代码如下:
module sigadd4_4(
IN1,
IN2,
OUT);
input signed [3:0] IN1,IN2;
output signed [3:0] OUT;
reg signed [3:0] OUT;

always @ (IN1 or IN2) begin
OUT = IN1 + IN2;
end
endmodule

仿真结果如下:
在这里插入图片描述
8比特位宽实验代码如下:
module sigadd8_5(
IN1,
IN2,
OUT);
input signed [7:0] IN1,IN2;
output signed [4:0] OUT;
reg signed [4:0] OUT;

always @ (IN1 or IN2) begin
OUT = IN1 + IN2;
end
endmodule
仿真结果如下:
在这里插入图片描述
学生实验

不改变流水线的级数,把加法器的输入信号改成8比特位宽,编译,波形仿真,和不带流水线的情况对比一下,你有什么结论? 在8比特输入位宽的情况下,在输入上再添加一级流水线,观察编译和仿真的结果,你有什么结论?

不改变流水线的级数,8比特位宽实验代码如下:
module liadd8_5(
IN1,
IN2,
CLK,
OUT);

input [7:0] IN1,IN2;
input CLK;
output [4:0] OUT;
reg [7:0] in1_dir,in2_dir;
reg [4:0] adder_out,OUT;

always @ (posedge CLK) begin
in1_dir <= IN1;
in2_dir <= IN2;
OUT <= adder_out;
end

always @ (in1_dir or in2_dir) begin
adder_out = in1_dir + in2_dir;
end
endmodule

仿真结果如下:
在这里插入图片描述
不改变流水线的级数,8比特位宽实验代码如下:
module liadd2_4_5(
IN1,
IN2,
CLK,
OUT);

input [3:0] IN1,IN2;
input CLK;
output [4:0] OUT;
reg [3:0] in1_d1r,in2_d1r,in1_d2r,in2_d2r;
reg [4:0] adder_out,OUT;

always @ (posedge CLK) begin
in1_d1r <= IN1;
in2_d2r <= IN2;
in1_d2r <= in1_d1r;
in2_d2r <= in2_d1r;
OUT <= adder_out;

end

always @ (in1_d2r or in2_d2r) begin
adder_out = in1_d2r + in2_d2r;
end
endmodule

仿真结果如下:
在这里插入图片描述
学生实验
(1)改变乘法器的输入位宽为8比特,编译,波形仿真,观察信号毛刺的时间长度。
(2)选一款没有硬件乘法器的FPGA芯片(例如Cyclone EP1C6)对比8比特的乘法器和加法器两者编译之后的资源开销(Logic Cell的数目)
(3)编写一个输入和输出都有D触发器的流水线乘法器代码,编译后波形仿真,观察组合逻辑延迟和毛刺的时间,和不带流水线的情况下对比。

(1)实验代码如下:
module unmul8_8(
IN1,
IN2,
OUT);

input [7:0] IN1,IN2;
output [7:0] OUT;

reg [7:0] OUT;

always @ (IN1 or IN2) begin
OUT = IN1 * IN2;
end
endmodule

仿真结果如下:
在这里插入图片描述
(2)实验代码如下:
module no_unmul8_8(
IN1,
IN2,
OUT);
input [7:0] IN1,IN2;
output [7:0] OUT;
reg [7:0] OUT;

always @ (IN1 or IN2) begin
OUT = IN1 * IN2;
end
endmodule

资源消耗对比如下:
在这里插入图片描述
在这里插入图片描述
(3)实验代码如下:
module li2mul4_8(
IN1,
IN2,
CLK,
OUT);

input signed [3:0] IN1,IN2;
input CLK;
output signed[7:0] OUT;

reg signed [7:0] muler_out,OUT;
reg signed [3:0] in1_d1r,in2_d1r;

always @ (posedge CLK) begin
in1_d1r <= IN1;
in2_d1r <= IN2;
OUT <= muler_out;
end

always @ (in1_d1r or in2_d1r) begin
muler_out = in1_d1r * in2_d1r;
end
endmodule

仿真结果如下:
在这里插入图片描述
学生实验
(1)设计一个最简单的计数器,只有一个CLK输入和一个OVerflow输出,当计数到最大值的时钟周期CLK输出1
(2)设计复杂的计数器,和本例相似,带有多种信号,其中同步清零CLR的优先级最高,使能EN次之,LOAD最低。

(1)实验代码如下:
module countc_o(
clk,
cin,
cout,
Overflow,
Rst_n);

input clk;
input cin;
input Rst_n;
output reg cout = 0;
output reg [3:0] Overflow = 0;

always @(posedge cin or posedge clk or negedge Rst_n)
if(!Rst_n) Overflow = 0;
else if(clk) Overflow = 0;
else if(Overflow == 9)begin
Overflow<=0;cout<=1;
end
else begin
Overflow<=Overflow + 1;cout<=0;
end

endmodule

仿真结果如下:
在这里插入图片描述
(2)实验代码如下:
module complex_count(
RST , // 异步复位, 高有效
CLK , // 时钟,上升沿有效
EN , // 输入的计数使能,高有效
CLR , // 输入的清零信号,高有效
LOAD , // 输入的数据加载使能信号,高有效
DATA , // 输入的加载数据信号
CNTVAL, // 输出的计数值信号
OV );// 计数溢出信号,计数值为最大值时该信号为1

input RST , CLK , EN , CLR , LOAD ;
input [3:0] DATA ;
output [3:0] CNTVAL;
output OV;

reg [3:0] CNTVAL, cnt_next;
reg OV;
// 电路编译参数,最大计数值
parameter CNT_MAX_VAL = 9;

// 组合逻辑,生成cnt_next
// 计数使能最优先,清零第二优先,加载第三优先
always @(EN or CLR or LOAD or DATA or CNTVAL) begin
if(CLR) begin // 使能有效
if(EN) begin // 清零有效
cnt_next = 0;
end
else begin // 清零无效
if(LOAD) begin // 加载有效
cnt_next = DATA;
end
else begin // 加载无效,正常计数
// 使能有效,清零和加载都无效,根据当前计数值计算下一值
if(CNTVAL < CNT_MAX_VAL) begin // 未计数到最大值, 下一值加1
cnt_next = CNTVAL + 1’b1;
end
else begin // 计数到最大值,下一计数值为0
cnt_next = 0;
end
end // else LOAD
end // else CLR
end // if EN
else begin // 使能无效,计数值保持不动
cnt_next = CNTVAL;
end // else EN
end

// 时序逻辑 更新下一时钟周期的计数值
// CNTVAL 会被编译为D触发器
always @ (posedge CLK or posedge RST) begin
if(RST)
CNTVAL <= 0;
else
CNTVAL <= cnt_next;
end

// 组合逻辑,生成OV
always @ (CNTVAL) begin
if(CNTVAL == CNT_MAX_VAL)
OV = 1;
else
OV = 0;
end

endmodule

仿真结果如下:
在这里插入图片描述
学生实验
设计一个用于识别2进制序列“1011”的状态机
基本要求:
电路每个时钟周期输入1比特数据,当捕获到1011的时钟周期,电路输出1,否则输出0
使用序列101011010作为输出的测试序列
扩展要求:
给你的电路添加输入使能端口,只有输入使能EN为1的时钟周期,才从输入的数据端口向内部获取1比特序列数据。

基本要求实验代码如下:
module zhuangtaiji(
CLK , // clock
RST , // reset
CENT1IN , // input 1 cent coin
TINOUT ); // output 1 tin cola

input CLK ;
input RST ;
input CENT1IN ;
output TINOUT ;

parameter ST_0_CENT = 0;
parameter ST_1_CENT = 1;
parameter ST_2_CENT = 2;
parameter ST_3_CENT = 3;
parameter ST_4_CENT = 4;

reg [4-2:0]stateR ;
reg [4-2:0]next_state ;
reg TINOUT ;

// calc next state
always @ (CENT1IN or stateR) begin
case (stateR)
ST_0_CENT :begin if(CENT1IN) next_state = ST_1_CENT ; else next_state = ST_0_CENT; end
ST_1_CENT :begin if(CENT1IN) next_state = ST_2_CENT ; else next_state = ST_0_CENT; end
ST_2_CENT :begin if(CENT1IN) next_state = ST_3_CENT ; else next_state = ST_0_CENT; end
ST_3_CENT :begin if(CENT1IN) next_state = ST_4_CENT ; else next_state = ST_0_CENT; end
ST_4_CENT :begin next_state = ST_0_CENT;end
endcase
end

// calc output
always @ (stateR) begin
if(stateR == ST_4_CENT)
TINOUT = 1’b1;
else
TINOUT = 1’b0;
end

// state DFF
always @ (posedge CLK or posedge RST)begin
if(RST)
stateR <= ST_0_CENT;
else
stateR <= next_state;
end

endmodule

扩展要求实验代码如下:
module shinengzhuangtaiji(
CLK , // clock
RST , // reset
CENT1IN , // input 1 cent coin
EN ,
TINOUT ); // output 1 tin cola

input CLK ;
input RST ;
input CENT1IN ;
input EN;
output TINOUT ;

parameter ST_0_CENT = 0;
parameter ST_1_CENT = 1;
parameter ST_2_CENT = 2;
parameter ST_3_CENT = 3;
parameter ST_4_CENT = 4;

reg [4-2:0]stateR ;
reg [4-2:0]next_state ;
reg TINOUT ;

// calc next state
always @ (CENT1IN or stateR) begin
if(EN)begin
case (stateR)
ST_0_CENT :begin if(CENT1IN) next_state = ST_1_CENT ; else next_state = ST_0_CENT; end
ST_1_CENT :begin if(CENT1IN) next_state = ST_2_CENT ; else next_state = ST_0_CENT; end
ST_2_CENT :begin if(CENT1IN) next_state = ST_3_CENT ; else next_state = ST_0_CENT; end
ST_3_CENT :begin if(CENT1IN) next_state = ST_4_CENT ; else next_state = ST_0_CENT; end
ST_4_CENT :begin next_state = ST_0_CENT;end
endcase
end
else
if(next_state!=ST_0_CENT)
next_state = ST_0_CENT;
end

// calc output
always @ (stateR) begin
if(stateR == ST_4_CENT)
TINOUT = 1’b1;
else
TINOUT = 1’b0;
end

// state DFF
always @ (posedge CLK or posedge RST)begin
if(RST)
stateR <= ST_0_CENT;
else
stateR <= next_state;
end

endmodule

学生实验
设计一个如本节“电路描述”部分的“带加载使能和移位使能的并入串出”的移位寄存器,电路的RTL结构图如“电路描述”部分的RTL结构图所示。

实验代码如下:
module yiweijicunqi(
RST ,
CLK ,
LOAD ,
EN ,
IN ,
OUT );

input RST, CLK, EN,LOAD;
input [3:0]IN;
output OUT;
reg [3:0] shift_R;
reg OUT;

always @ (posedge CLK or posedge RST or posedge LOAD) begin
if(RST)
shift_R[3:0] <= 0;
else begin
if(LOAD) begin
shift_R[3:0] <= IN[3:0];
end
else begin
if(EN) begin
OUT = shift_R[3];
shift_R[3:1] <= shift_R[2:0];
shift_R[0] <= 0;
end
else begin
shift_R[3:0] <= shift_R[3:0];
end
end
end
end
endmodule

RTL Viewer:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43303087/article/details/83959855