牛客Verilog刷题篇

输入序列连续的序列检测_牛客题霸_牛客网

序列检测

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 );
      end

    endmodule

计数器(状态计数法)

  • 用一个 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);
      end

    endmodule

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:0out2

类型 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。

相关推荐
Hello-FPGA11 小时前
基于RFSOC FPGA ZCU216 的CoaXPress 采集demo
fpga开发
9527华安12 小时前
FPGA基于ADV7182解码PAL视频,Video Processing Subsystem去隔行,提供6套工程源码和技术支持
fpga开发·音视频·pal·adv7182
hahaha601613 小时前
数字图像时域滤波或者3D降噪算法FPGA实现
算法·计算机视觉·fpga开发
GateWorld13 小时前
Xilinx 7系列FPGA时钟网络详解
fpga开发·时钟网络·xilinx 7系列
szxinmai主板定制专家1 天前
X86 工控机 vs RK3588 异构主控:AMR 控制器 BOM、散热、长期运维对比
运维·stm32·单片机·嵌入式硬件·fpga开发·am62x
szxinmai主板定制专家2 天前
AMR 项目落地:机器人控制器硬件定制化需求复盘
arm开发·单片机·fpga开发·系统架构·机器人·am62x
FPGA小迷弟2 天前
FPGA 与卫星:从星载硬件到在轨智能的完整技术解析
fpga开发·架构·fpga·1024程序员节·无线电
NamoAmitabha1283 天前
CPU 内部结构是什么?---deepseek
fpga开发
abc light3 天前
ARM 裸机开发(6)——时钟树与定时器
arm开发·单片机·fpga开发
156082072193 天前
JFMZQ28DR、JFMZQ68DR、RFsoc XCZU47DR、XCZU48DR 信号处理板
fpga开发·信号处理