序列检测
VL25 输入序列连续的序列检测(已做)
请编写一个序列检测模块,检测输入信号a是否满足01110001序列,当信号满足该序列,给出指示信号match。
模块的接口信号图如下:

模块的时序图如下:

请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能
输入描述:
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
a:单比特信号,待检测的数据
输出描述:
match:当输入信号a满足目标序列,该信号为1,其余时刻该信号为0
状态机实现

`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
reg[3:0] present_state,next_state;
parameter s0=4'b0000,s1=4'b0001,s2=4'b0010,s3=4'b0011,s4=4'b0100,s5=4'b0101,s6=4'b0110,s7=4'b0111,s8=4'b1000;
//寄存器
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) present_state<=s0;
else present_state<=next_state;
end
//状态转移
always@(*)
begin
case(present_state)
s0:if(a==0) next_state=s1;
else next_state=s0;
s1:if(a==1) next_state=s2;
else next_state=s1;
s2:if(a==1) next_state=s3;
else next_state=s1;
s3:if(a==1) next_state=s4;
else next_state=s1;
s4:if(a==0) next_state=s5;
else next_state=s0;
s5:if(a==0) next_state=s6;
else next_state=s2;
s6:if(a==0) next_state=s7;
else next_state=s2;
s7:if(a==1) next_state=s8;
else next_state=s1;
s8:if(a==1) next_state=s3;
else next_state=s1;
default: next_state=s0;
endcase
end
//输出模块
always @(posedge clk or negedge rst_n)
begin
if (!rst_n) match <= 1'b0;
else match <= (present_state == s8);
end
endmodule
或者使用独热码
testbench
`timescale 1ns/1ns
module testbench();
reg clk, rst_n;
reg a;
wire match;
// 时钟独立生成,不会死循环
always #1 clk = ~clk;
// 激励 + 结束仿真(关键:必须有 $finish,否则超时!)
initial begin
$dumpfile("out.vcd");
$dumpvars(0, testbench);
// 初始化
clk = 0;
rst_n = 0;
a = 0;
// 复位
#2;
rst_n = 1;
// 正确序列:0 1 1 1 0 0 0 1(让状态机走到 s8,输出 match)
#2; a = 0;
#2; a = 1;
#2; a = 1;
#2; a = 1;
#2; a = 0;
#2; a = 0;
#2; a = 0;
#2; a = 1;
// 保持一下
#10;
// 结束仿真(解决超时的核心!)
$finish;
end
// 例化
sequence_detect dut(
.clk(clk),
.rst_n(rst_n),
.a(a),
.match(match)
);
endmodule

"移位寄存器 + 组合逻辑"实现
-
使用一个 8 位移位寄存器
shift_reg,每个时钟上升沿将输入a移入最低位(左移)。 -
经过 8 个时钟后,寄存器内容即为最近 8 个输入的历史。
-
组合逻辑比较
shift_reg是否等于目标序列8'b01110001,相等时match输出高电平`timescale 1ns/1ns
module sequence_detect (
input clk,
input rst_n,
input a,
output reg match
);
localparam Q=8'b01110001;
reg [7:0] shift_reg;// 移位寄存器 always @(posedge clk or negedge rst_n) begin if (!rst_n) shift_reg <= 8'b0; else shift_reg <= {shift_reg[6:0], a}; // 左移,新数据放入 LSB end // 组合逻辑输出匹配信号 always@(posedge clk,negedge rst_n) begin if(!rst_n) match=1'b0; else match = (shift_reg == Q ); endendmodule
计数器(状态计数法)
-
用一个 4 位计数器
cnt(0~8)表示当前已连续匹配的序列长度。 -
每个时钟根据当前
cnt和输入a决定下一cnt(本质是简化版的状态机)。 -
当
cnt == 8时输出match = 1,并依据重叠规则跳转到下一状态。`timescale 1ns/1ns
module sequence_detect (
input clk,
input rst_n,
input a,
output reg match
);reg [3:0] cnt, next_cnt; // 0~8 // 时序状态更新 always @(posedge clk or negedge rst_n) begin if (!rst_n) cnt <= 4'd0; else cnt <= next_cnt; end // 组合逻辑:下一状态 always @(*) begin case (cnt) 4'd0: next_cnt = (a == 0) ? 4'd1 : 4'd0; 4'd1: next_cnt = (a == 1) ? 4'd2 : 4'd1; 4'd2: next_cnt = (a == 1) ? 4'd3 : 4'd1; 4'd3: next_cnt = (a == 1) ? 4'd4 : 4'd1; 4'd4: next_cnt = (a == 0) ? 4'd5 : 4'd0; 4'd5: next_cnt = (a == 0) ? 4'd6 : 4'd2; 4'd6: next_cnt = (a == 0) ? 4'd7 : 4'd2; 4'd7: next_cnt = (a == 1) ? 4'd8 : 4'd1; 4'd8: next_cnt = (a == 1) ? 4'd3 : 4'd1; default: next_cnt = 4'd0; endcase end // 输出 match(组合逻辑,检测到 cnt==8 立即输出) always @(posedge clk or negedge rst_n) begin if(!rst_n) match=1'b0; else match = (cnt == 4'd8); endendmodule
VL26 含有无关项的序列检测(已做)
请编写一个序列检测模块,检测输入信号a是否满足011XXX110序列(长度为9位数据,前三位是011,后三位是110,中间三位不做要求),当信号满足该序列,给出指示信号match。
程序的接口信号图如下:

程序的功能时序图如下:

请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能。 要求代码简洁,功能完整。
输入描述:
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
a:单比特信号,待检测的数据
输出描述:
match:当输入信号a满足目标序列,该信号为1,其余时刻该信号为0
移位寄存器实现
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
reg[8:0] shift_reg;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
shift_reg<=9'b0;
else
shift_reg<={shift_reg[7:0],a};
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) match=1'b0;
else match <= (shift_reg[8:6] == 3'b011) && (shift_reg[2:0] == 3'b110);
end
endmodule
match是在shift_reg完整的下一拍拉高的,所以用时序逻辑
testbench
`timescale 1ns/1ns
module testbench();
reg clk,rst_n;
reg a;
wire match;
always #1 clk=~clk;
initial
begin
$dumpfile("out.vcd");
$dumpvars(0, testbench);
clk=0;rst_n=0;a=0;
#2 rst_n=1;
#2 a=0;
#2 a=1;
#2 a=1;
#2 a=0;
#2 a=1;
#2 a=1;
#2 a=1;
#2 a=1;
#2 a=0;
#10
$finish;
end
sequence_detect dut(
.clk(clk),
.rst_n(rst_n),
.a(a),
.match(match)
);
endmodule

这种采用移位寄存器实现的比较容易
若采用状态机,需考虑重复序列的比较复杂,(中间3位xxx)
VL27 不重叠序列检测(已做)
请编写一个序列检测模块,检测输入信号(a)是否满足011100序列, 要求以每六个输入为一组,不检测重复序列,例如第一位数据不符合,则不考虑后五位。一直到第七位数据即下一组信号的第一位开始检测。当信号满足该序列,给出指示信号match。当不满足时给出指示信号not_match。
模块的接口信号图如下:

模块的时序图如下:

请使用Verilog HDL实现以上功能,要求使用状态机实现,画出状态转化图。并编写testbench验证模块的功能。
输入描述:
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
a:单比特信号,待检测的数据
输出描述:
match:当输入信号a满足目标序列,该信号为1,其余时刻该信号为0
not_match:当输入信号a不满足目标序列,该信号为1,其余时刻该信号为0
用状态机实现
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
output reg match,
output reg not_match
);
localparam s0=4'b0000,s1=4'b0001,s2=4'b0010,s3=4'b0011,s4=4'b0100,s5=4'b0101,
f1=4'b0110,f2=4'b0111,f3=4'b1000,f4=4'b1001,f5=4'b1010;
reg[3:0] present_state,next_state;
//
always@(posedge clk or negedge rst_n)
if(!rst_n) present_state<=s0;
else present_state<=next_state;
//
always@(*)
case(present_state)
s0:next_state=data?f1:s1;
s1:next_state=data?s2:f2;
s2:next_state=data?s3:f3;
s3:next_state=data?s4:f4;
s4:next_state=data?f5:s5;
s5:next_state=s0;
f1:next_state=f2;
f2:next_state=f3;
f3:next_state=f4;
f4:next_state=f5;
f5:next_state=s0;
default:next_state=s0;
endcase
//
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
match<=0;
not_match<=0;
end
else
begin
match<=(present_state==s5)&&(data==0);
not_match<=((present_state==s5)&&(data==1)||present_state==f5);
end
endmodule
testbench
`timescale 1ns/1ns
module testbench();
reg clk,rst_n;
reg data;
wire match;
wire not_match;
initial begin
$dumpfile("out.vcd");
$dumpvars(0,testbench);
clk = 0;
rst_n = 0;
data=0;
#2 rst_n=1;
#2 data=1;
#2 data=1;
#2 data=1;
#2 data=0;
#2 data=0;
//
//#2 data=0;
#3 data=1;
#2 data=0;
#2 data=0;
#2 data=1;
#2 data=1;
#10
$finish;
end
always #1 clk = !clk;
sequence_detect dut(
.clk(clk),
.rst_n(rst_n),
.data(data),
.not_match(not_match),
.match(match)
);
endmodule

VL28 输入序列不连续的序列检测
题目描述:
请编写一个序列检测模块,输入信号端口为data,表示数据有效的指示信号端口为data_valid。当data_valid信号为高时,表示此刻的输入信号data有效,参与序列检测;当data_valid为低时,data无效,抛弃该时刻的输入。当输入序列的有效信号满足0110时,拉高序列匹配信号match。
模块的接口信号图如下:

模块的时序图如下:

请使用状态机实现以上功能,画出状态转移图并使用Verilog HDL编写代码实现以上功能,并编写testbench验证模块的功能.
输入描述:
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
data:单比特信号,待检测的数据
data_valid:输入信号有效标志,当该信号为1时,表示输入信号有效
输出描述:
match:当输入信号data满足目标序列,该信号为1,其余时刻该信号为0
时序逻辑
VL29 信号发生器
题目描述:
请编写一个信号发生器模块,根据波形选择信号wave_choise发出相应的波形:wave_choice=0时,发出方波信号;wave_choice=1时,发出锯齿波信号;wave_choice=2时,发出三角波信号。
模块的接口信号图如下:


请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能
输入描述:
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
wave_choise:2比特位宽的信号,根据该信号的取值不同,输出不同的波形信号
输出描述:
wave:5比特位宽的信号,根据wave_choise的值,输出不同波形的信号
VL30 数据串转并电路
实现串并转换电路,输入端输入单bit数据,每当本模块接收到6个输入数据后,输出端输出拼接后的6bit数据。本模块输入端与上游的采用valid-ready双向握手机制,输出端与下游采用valid-only握手机制。数据拼接时先接收到的数据放到data_b的低位。
电路的接口如下图所示。valid_a用来指示数据输入data_a的有效性,valid_b用来指示数据输出data_b的有效性;ready_a用来指示本模块是否准备好接收上游数据,本模块中一直拉高;clk是时钟信号;rst_n是异步复位信号。


输入描述:
input clk ,
input rst_n ,
input valid_a ,
input data_a
输出描述:
output reg ready_a ,
output reg valid_b ,
output reg [5:0] data_b
VL31 数据累加输出
实现串行输入数据累加输出,输入端输入8bit数据,每当模块接收到4个输入数据后,输出端输出4个接收到数据的累加结果。输入端和输出端与上下游的交互采用valid-ready双向握手机制。要求上下游均能满速传输时,数据传输无气泡,不能由于本模块的设计原因产生额外的性能损失。
电路的接口如下图所示。valid_a用来指示数据输入data_in的有效性,valid_b用来指示数据输出data_out的有效性;ready_a用来指示本模块是否准备好接收上游数据,ready_b表示下游是否准备好接收本模块的输出数据;clk是时钟信号;rst_n是异步复位信号。


输入描述:
input clk ,
input rst_n ,
input [7:0] data_in ,
input valid_a ,
input ready_b
输出描述:
output ready_a ,
output reg valid_b ,
output reg [9:0] data_out
VL32 非整数倍数据位宽转换24to128
实现数据位宽转换电路,实现24bit数据输入转换为128bit数据输出。其中,先到的数据应置于输出的高bit位。
电路的接口如下图所示。valid_in用来指示数据输入data_in的有效性,valid_out用来指示数据输出data_out的有效性;clk是时钟信号;rst_n是异步复位信号。


输入描述:
input clk ,
input rst_n ,
input valid_in ,
input [23:0] data_in
输出描述:
output reg valid_out ,
output reg [127:0] data_out
VL33 非整数倍数据位宽转换8to12
实现数据位宽转换电路,实现8bit数据输入转换为12bit数据输出。其中,先到的数据应置于输出的高bit位。
电路的接口如下图所示。valid_in用来指示数据输入data_in的有效性,valid_out用来指示数据输出data_out的有效性;clk是时钟信号;rst_n是异步复位信号。

波形示意图如下:

输入描述:
input clk ,
input rst_n ,
input valid_in ,
input [7:0] data_in
输出描述:
output reg valid_out,
output reg [11:0] data_out
VL34 整数倍数据位宽转换8to16
实现数据位宽转换电路,实现8bit数据输入转换为16bit数据输出。其中,先到的8bit数据应置于输出16bit的高8位。
电路的接口如下图所示。valid_in用来指示数据输入data_in的有效性,valid_out用来指示数据输出data_out的有效性;clk是时钟信号;rst_n是异步复位信号


输入描述:
input clk ,
input rst_n ,
input valid_in ,
input [7:0] data_in
输出描述:
output reg valid_out,
output reg [15:0] data_out
VL35 状态机-非重叠的序列检测
设计一个状态机,用来检测序列 10111,要求:
1、进行非重叠检测 即101110111 只会被检测通过一次
2、寄存器输出且同步输出结果
注意rst为低电平复位
信号示意图:

波形示意图:

输入描述:
输入信号 clk rst data
类型 wire
输出描述:
输出信号 flag
类型 reg
VL36 状态机-重叠序列检测
设计一个状态机,用来检测序列 1011,要求:
1、进行重叠检测 即10110111 会被检测通过2次
2、寄存器输出,在序列检测完成下一拍输出检测有效
注意rst为低电平复位
信号示意图:

波形示意图:

输入描述:
输入信号 clk rst data
类型 wire
输出描述:
输出信号 flag
类型 reg
VL37 时钟分频(偶数)
请使用D触发器设计一个同时输出2/4/8分频的50%占空比的时钟分频器
注意rst为低电平复位
信号示意图:

波形示意图:

输入描述:
输入信号 clk rst
类型 wire
输出描述:
输出信号 clk_out2 clk_out4 clk_out8
类型 wire
VL38 自动贩售机1
设计一个自动贩售机,输入货币有三种,为0.5/1/2元,饮料价格是1.5元,要求进行找零,找零只会支付0.5元。
ps:
投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号
注意rst为低电平复位
信号示意图:

d1 0.5元
d2 1元
d3 2元
out1 饮料
out2 零钱
波形示意图:

对应的激励源:

输入描述:
输入信号 clk rst d1 d2 d3
类型 wire
输出描述:
输出信号 out1 [1:0]out2
类型 reg
VL39 自动贩售机2
题目描述:
设计一个自动贩售机,输入货币有两种,为0.5/1元,饮料价格是1.5/2.5元,要求进行找零,找零只会支付0.5元。
ps:
1、投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号
2、此题忽略出饮料后才能切换饮料的问题
注意rst为低电平复位
信号示意图:
d1 0.5
d2 1
sel 选择饮料
out1 饮料1
out2 饮料2
out3 零钱

波形示意图:


输入描述:
输入信号 clk rst d1 d2 sel
类型 wire
输出描述:
输出信号 out1 out2 out3
类型 reg
VL40 占空比50%的奇数分频
设计一个同时输出7分频的时钟分频器,占空比要求为50%
注意rst为低电平复位
信号示意图:

波形示意图:

输入描述:
输入信号 clk_in rst
类型 wire
输出描述:
输出信号 clk_out7
类型 wire
VL41 任意小数分频
请设计一个可以实现任意小数分频的时钟分频器,比如说8.7分频的时钟信号
注意rst为低电平复位
提示:
其实本质上是一个简单的数学问题,即如何使用最小公倍数得到时钟周期的分别频比。
设小数为nn,此处以8.7倍分频的时钟周期为例。
首先,由于不能在硬件上进行小数的运算(比如2.1个时钟这种是不现实的,也不存在3.3个寄存器),小数分频不能做到分频后每个时钟周期都是源时钟的nn倍,也无法实现占空比为1/2,因此,考虑小数分频,其实现方式应当为53个clkout时钟周期是10个clkin时钟周期的8.7倍。
信号示意图:

波形示意图:

输入描述:
输入信号 clk_in rst
类型 wire
输出描述:
输出信号 clk_out
类型 wire
VL42 无占空比要去的奇数分频
题目描述:
请设计一个同时输出5分频的时钟分频器,本题对占空比没有要求
注意rst为低电平复位
信号示意图:

波形示意图:

输入描述:
输入信号 clk_in rst
类型 wire
输出描述:
输出信号 clk_out5
类型 wire
VL43 根据状态转移写状态机-三段式
题目描述:

如图所示为两种状态机中的一种,请根据状态转移图写出代码,状态转移线上的0/0等表示的意思是过程中data/flag的值。
要求:
1、 必须使用对应类型的状态机
2、 使用三段式描述方法,输出判断要求要用到对现态的判断
注意rst为低电平复位
信号示意图:

波形示意图:

输入描述:
输入信号 clk rst data
类型 wire
输出描述:
输出信号 flag
类型 reg
VL44 根据状态转移写状态机-二段式
题目描述:

如图所示为两种状态机中的一种,请根据状态转移图写出代码,状态转移线上的0/0等表示的意思是过程中data/flag的值。
要求:
1、 必须使用对应类型的状态机
2、 使用二段式描述方法
注意rst为低电平复位
信号示意图:

波形示意图:

激励描述如下:

输入描述:
输入信号 clk rst data
类型 wire
输出描述:
输出信号 flag
类型 reg
跨时钟域传输
VL45 异步FIFO
请根据题目中给出的双口RAM代码和接口描述,实现异步FIFO,要求FIFO位宽和深度参数化可配置。
电路的接口如下图所示

双口RAM端口说明:

同步FIFO端口说明:

双口RAM代码如下,可在本题答案中添加并例化此代码。
module dual_port_RAM #(parameter DEPTH = 16,
parameter WIDTH = 8)(
input wclk
,input wenc
,input [$clog2(DEPTH)-1:0] waddr //深度对2取对数,得到地址的位宽。
,input [WIDTH-1:0] wdata //数据写入
,input rclk
,input renc
,input [$clog2(DEPTH)-1:0] raddr //深度对2取对数,得到地址的位宽。
,output reg [WIDTH-1:0] rdata //数据输出
);
reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];
always @(posedge wclk) begin
if(wenc)
RAM_MEM[waddr] <= wdata;
end
always @(posedge rclk) begin
if(renc)
rdata <= RAM_MEM[raddr];
end
endmodule
输入描述:
input wclk ,
input rclk ,
input wrstn ,
input rrstn ,
input winc ,
input rinc ,
input [WIDTH-1:0] wdata
输出描述:
output wire wfull ,
output wire rempty ,
output wire [WIDTH-1:0] rdata
VL46 同步FIFO
根据题目提供的双口RAM代码和接口描述,实现同步FIFO,要求FIFO位宽和深度参数化可配置。
电路的接口如下图所示。

端口说明如下表。
双口RAM端口说明:

同步FIFO端口说明:

双口RAM代码如下,可在答案中添加并例化此代码。
module dual_port_RAM #(parameter DEPTH = 16,
parameter WIDTH = 8)(
input wclk
,input wenc
,input [$clog2(DEPTH)-1:0] waddr //深度对2取对数,得到地址的位宽。
,input [WIDTH-1:0] wdata //数据写入
,input rclk
,input renc
,input [$clog2(DEPTH)-1:0] raddr //深度对2取对数,得到地址的位宽。
,output reg [WIDTH-1:0] rdata //数据输出
);
reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];
always @(posedge wclk) begin
if(wenc)
RAM_MEM[waddr] <= wdata;
end
always @(posedge rclk) begin
if(renc)
rdata <= RAM_MEM[raddr];
end
endmodule
输入描述:
input clk ,
input rst_n ,
input winc ,
input rinc ,
input [WIDTH-1:0] wdata
输出描述:
output reg wfull ,
output reg rempty ,
output wire [WIDTH-1:0] rdata
VL47 格雷码计数器
实现4bit位宽的格雷码计数器。
电路的接口如下图所示。

输入描述:
input clk,
input rst_n
输出描述:
output reg [3:0] gray_out
VL48 多bit MUX同步器
在data_en为高期间,data_in将保持不变,data_en为高至少保持3个B时钟周期。表明,当data_en为高时,可将数据进行同步。
本题中data_in端数据变化频率很低,相邻两个数据间的变化,至少间隔10个B时钟周期。
电路的接口如下图所示。端口说明如下表所示。


输入描述:
input clk_a ,
input clk_b ,
input arstn ,
input brstn ,
input [3:0] data_in ,
input data_en
输出描述:
output reg [3:0] dataout
VL49 脉冲同步电路
从A时钟域提取一个单时钟周期宽度脉冲,然后在新的时钟域B建立另一个单时钟宽度的脉冲。
A时钟域的频率是B时钟域的10倍;A时钟域脉冲之间的间隔很大,无需考虑脉冲间隔太小的问题。
电路的接口如下图所示。data_in是脉冲输入信号,data_out是新的脉冲信号;clk_fast是A时钟域时钟信号,clk_slow是B时钟域时钟信号;rst_n是异步复位信号。

输入描述:
input clk_fast ,
input clk_slow ,
input rst_n ,
input data_in
输出描述:
output dataout
计数器
VL50 简易秒表
请编写一个模块,实现简易秒表的功能:具有两个输出,当输出端口second从1-60循环计数,每当second计数到60,输出端口minute加一,一直到minute=60,暂停计数。
模块的接口信号图如下:

模块的时序图如下:


请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能
输入描述:
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
输出描述:
second:6比特位宽,秒表的秒读数
minute:6比特位宽,秒表的分读数
VL51 可置位计数器
请编写一个十六进制计数器模块,计数器输出信号递增每次到达0,给出指示信号zero,当置位信号set 有效时,将当前输出置为输入的数值set_num。
模块的接口信号图如下:

模块的时序图如下:

请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能
输入描述:
clk:时钟信号
rst_n:复位信号,低电平有效
set:置位指示信号,当该信号有效时,表示将输出信号强制置为set_num
set_num:4比特信号,当set信号有效时,将该信号的数字赋予输出信号number
输出描述:
zero:过零指示信号,当number计数到0时,该信号为1,其余时刻为0
number:4比特位宽,表示计数器的当前读数
VL52 加减计数器
请编写一个十进制计数器模块,当mode信号为1,计数器输出信号递增,当mode信号为0,计数器输出信号递减。每次到达0,给出指示信号zero。
模块的接口信号图如下:

模块的时序图如下:

请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能
输入描述:
clk:系统时钟信号
rst_n:复位信号,低电平有效
mode:模式选择信号,当该信号为1,计数器每个时钟加一;为0,则每个时钟减一。
输出描述:
number:4比特位宽,计数器当前输出读数。
zero:过零指示信号,当number为0时,该信号为1,其他时刻为0.
存储器
VL53 单端口RAM
题目描述:
设计一个单端口RAM,它有: 写接口,读接口,地址接口,时钟接口和复位;存储宽度是4位,深度128。
注意rst为低电平复位
信号示意图:

输入描述:
输入信号 enb, clk, rst addr w_data
类型 wire
在testbench中,clk为周期5ns的时钟,rst为低电平复位
输出描述:
输出信号 r_data
类型 wire
VL54 RAM的简单实现
实现一个深度为8,位宽为4bit的双端口RAM,数据全部初始化为0000。具有两组端口,分别用于读数据和写数据,读写操作可以同时进行。当读数据指示信号read_en有效时,通过读地址信号read_addr读取相应位置的数据read_data,并输出;当写数据指示信号write_en有效时,通过写地址信号write_addr 和写数据write-data,向对应位置写入相应的数据。
程序的信号接口图如下:

模块的时序图如下:

使用Verilog HDL实现以上功能并编写testbench验证。
输入描述:
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
read_en,write_en:单比特信号,读/写使能信号,表示进行读/写操作
read_addr,write_addr:8比特位宽的信号,表示读/写操作对应的地址
write_data:4比特位宽的信号,在执行写操作时写入RAM的数据
输出描述:
read_data:4比特位宽的信号,在执行读操作时从RAM中读出的数据
综合
VL55 Johnson Counter
请用Verilog实现4位约翰逊计数器(扭环形计数器),计数器的循环状态如下。
电路的接口如下图所示。


输入描述:
input clk ,
input rst_n
输出描述:
output reg [3:0] Q
VL56 流水线乘法器
实现4bit无符号数流水线乘法器设计。
电路的接口如下图所示。

输入描述:
input clk ,
input rst_n ,
input [size-1:0] mul_a ,
input [size-1:0] mul_b
输出描述:
output reg [size*2-1:0] mul_out
VL57 交通灯
要求实现一个交通红绿灯,具有红黄绿三个小指示灯和一个行人按钮,正常情况下,机动车道指示灯按照60时钟周期绿灯,5个时钟周期黄灯,10个时钟周期红灯循环。当行人按钮按下,如果剩余绿灯时间大于10个时钟,则缩短为10个时钟,小于10个时钟则保持不变。
注:机动车道的指示灯和人行道指示灯应该是配对的,当机动车道的灯为绿或者黄时,人行道的灯为红;当机动车道的灯为红时,人行道的灯为绿,为简便起见,只考虑机动车道的指示灯。
模块的信号接口图如下:

请使用VerilogHDL语言实现,并编写testbench验证功能。
输入描述:
clk:系统时钟信号
rst_n:复位信号,低电平有效
pass_request:行人按钮信号,当该信号为1,表示按钮按下,如果剩余绿灯时间大于10个时钟,则缩短为10个时钟,小于10个时钟则保持不变。
输出描述:
clock:交通灯倒计时读数
red:该信号为1,表示红灯亮,为0表示红灯不亮
yellow:该信号为1,表示黄灯亮,为0表示黄灯不亮
green:该信号为1,表示黄灯亮,为0表示黄灯不亮
VL58 游戏机计费程序
要求实现一个游戏机计费模块,某游戏机具有多个模式,价格不同:普通模式每分钟1元,畅玩模式每分钟收费2元,默认情况下为普通模式,在boost按键按下之后进入畅玩模式。
游戏机采用预付费模式,输入端口money的数值为预付费用,在set信号有效时,将money的数值读入。输出端口remain的数值为剩余费用,当费用小于10元时,黄色信号灯yellow亮起。当费用不足时,红色信号灯red亮起,同时关闭电脑。在游戏过程中可以通过set端口续费。每次set信号有效将此时刻money的数值加到remain之中。
注:在程序中以每个时钟周期代表一分钟,每个单位大小表示1元。
模块的信号接口图如下:

请使用VerilogHDL语言实现,并编写 testbench 验证功能。
输入描述:
clk:系统时钟信号
rst_n:复位信号,低电平有效
money:10bit位宽的数据,表示充值数额,当set信号有效时,将该信号的数值加到游戏余额remain中
set:充值信号,当信号等于1,表示用户充值。
boost:游戏机模式切换信号,为1时,表示进入畅玩模式,每个时钟扣费2,即remain减二,为0时,表示普通模式,remain每个时钟减一。
输出描述:
remain:10bit位宽的数据,表示余额,根据充值数额和游戏模式变化
yellow:指示灯,当remain大于0且小于10时,为1。
red:指示灯,当余额不足时为1,其余时刻为0。