牛客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: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。

相关推荐
my_daling5 小时前
DSMC通信协议理解,以及如何在FPGA上实现DSMC从设备(1)
学习·fpga开发
fei_sun16 小时前
FPGA&数字前端
fpga开发
尤老师FPGA17 小时前
HDMI数据的接收发送实验(九)
fpga开发
Flamingˢ19 小时前
ZYNQ + OV5640 视频系统开发(四):HDMI 显示链路
嵌入式硬件·fpga开发·硬件架构·音视频
LCMICRO-1331084774620 小时前
国产长芯微LDC5141完全P2P替代DAC80501,数模转换器 (DAC)
单片机·嵌入式硬件·fpga开发·硬件工程·dsp开发·数模转换器 dac
Nobody331 天前
锁存器与触发器
fpga开发
Nobody331 天前
跨时钟域信号处理的办法有哪些
fpga开发·信号处理
LCMICRO-133108477461 天前
长芯微LPC556D1完全P2P替代DAC8830,是引脚兼容的16位数模转换器,该系列产品为单通道、低功耗、缓冲电压输出型DAC
stm32·单片机·嵌入式硬件·fpga开发·硬件工程·电压输出型dac
北城笑笑1 天前
FPGA 与 市场主流芯片分类详解:SoC/CPU/GPU/DPU 等芯片核心特性与工程应用
前端·单片机·fpga开发·fpga