硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)

1.VL33 非整数倍数据位宽转换8to12

1.题目:

实现数据位宽转换电路,实现8bit数据输入转换为12bit数据输出。其中,先到的数据应置于输出的高bit位。

电路的接口如下图所示。valid_in用来指示数据输入data_in的有效性,valid_out用来指示数据输出data_out的有效性;clk是时钟信号;rst_n是异步复位信号。

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第1张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第2张图片

 


2.解题思路

        2.1 生成一个寄存器  存储数据,寄存器的大小应该要 大于 等于12。  

        2.2        8*3 ==  12*2

        2.3        第一个数据取8位 第二个数据取4位, 输出第一个信号, 第二个信号取后4位加上第三个数据,输出第二个信号。


3.解题代码

`timescale 1ns/1ns

module width_8to12(
	input 				   clk 		,   
	input 			      rst_n		,
	input				      valid_in	,
	input	[7:0]			   data_in	,
 
 	output  reg			   valid_out,
	output  reg [11:0]   data_out
);
reg[23:0] data; // data buffer
reg[1:0] cnt; // counter 

//本题时 1个时序题 采用 状态机 或者  提前模式
// 输入为  8为   输出 为12位    3*8 = 2*12; 
//设置三个状态。


//控制数据
always@(posedge clk or negedge rst_n)
	begin
		if(~rst_n)
			begin
				data <=0;
			end
		else
		 	begin
				if(valid_in == 1'b1)
					begin
						data <={data[15:0],data_in} ;
					end 
				else
					begin
						data <=data;
					end
			end
	end

always@(posedge clk or negedge rst_n)
	begin
		if(~rst_n)
			begin
				cnt <= 0;
			end
		else 
			begin
				if(cnt==2'd0 && valid_in==1'b1)
					begin
						cnt <= 2'd1;
					end
				else if(cnt == 2'd1 && valid_in == 1'b1)
					begin
						cnt <= 2'd2;
					end
				else if(cnt == 2'd2 && valid_in == 1'd1)
					begin
						cnt <=2'd0;
					end
			end
			
	end

always@(posedge clk or negedge rst_n)
	begin
		if(~rst_n)
			begin
				data_out <=0;
				valid_out <=0;
			end
		else 
			begin
				if(cnt == 2'd0)
					begin
						data_out <= data_out;
						valid_out <=0;
					end
				else if(cnt == 2'd1 && valid_in == 1'd1) 
					begin
						data_out <= {data[7:0],data_in[7:4]};
						valid_out <=1;
					end
				else if(cnt == 2'd2 && valid_in == 1'd1)
					begin
						data_out <= {data[3:0],data_in[7:0]};
						valid_out <=1;
					end
				else 
					begin
						valid_out <=0;
					end


			end
	end





endmodule


2.VL34 整数倍数据位宽转换8to16

1.题目:

实现数据位宽转换电路,实现8bit数据输入转换为16bit数据输出。其中,先到的8bit数据应置于输出16bit的高8位。

电路的接口如下图所示。valid_in用来指示数据输入data_in的有效性,valid_out用来指示数据输出data_out的有效性;clk是时钟信号;rst_n是异步复位信号。

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第3张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第4张图片 

  硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第5张图片


2.解题思路

        2.1 和上面那题差不多。

        2.2 首先是 第一个 和第二个数据 合并之后输出 第一个信号。


3.解题代码

`timescale 1ns/1ns

module width_8to16(
	input 				   clk 		,   
	input 				   rst_n		,
	input				      valid_in	,
	input	   [7:0]		   data_in	,
 
 	output	reg			valid_out,
	output   reg [15:0]	data_out
);

reg[23:0] data; // data buffer
reg[1:0] cnt; // counter 

//本题时 1个时序题 采用 状态机 或者  提前模式
// 输入为  8为   输出 为12位    3*8 = 2*12; 
//设置三个状态。


//控制数据
always@(posedge clk or negedge rst_n)
	begin
		if(~rst_n)
			begin
				data <=0;
			end
		else
		 	begin
				if(valid_in == 1'b1)
					begin
						data <={data[15:0],data_in} ;
					end 
				else
					begin
						data <=data;
					end
			end
	end

always@(posedge clk or negedge rst_n)
	begin
		if(~rst_n)
			begin
				cnt <= 0;
			end
		else 
			begin
				if(cnt==2'd0 && valid_in==1'b1)
					begin
						cnt <= 2'd1;
					end
				else if(cnt == 2'd1 && valid_in == 1'b1)
					begin
						cnt <= 2'd0;
					end
			end
			
	end

always@(posedge clk or negedge rst_n)
	begin
		if(~rst_n)
			begin
				data_out <=0;
				valid_out <=0;
			end
		else 
			begin
				if(cnt == 2'd0)
					begin
						data_out <= data_out;
						valid_out <=0;
					end
				else if(cnt == 2'd1 && valid_in == 1'd1) 
					begin
						data_out <= {data[7:0],data_in[7:0]};
						valid_out <=1;
					end
				else 
					begin
						valid_out <=0;
					end


			end
	end

endmodule

 



3.VL35 状态机-非重叠的序列检测

1.题目:

设计一个状态机,用来检测序列 10111,要求:

1、进行非重叠检测   即101110111 只会被检测通过一次

2、寄存器输出且同步输出结果

注意rst为低电平复位

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第6张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第7张图片 

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第8张图片 


2.解题思路

         2.1状态机 的解题思路, 时序同步输出。

        2.2 注意 存储空间 清除问题,因为是 非重叠。

        硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第9张图片 

 


3.解题代码

`timescale 1ns/1ns

module sequence_test1(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);
//*************code***********//
reg[4:0] data1; 


always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				flag <=0;
			end
		else
			begin
				if({data1[3:0],data} == 5'b10111)
					begin
						flag <=1;
						data1 <= 5'd0;
					end
				else
				  	begin
						flag <=0;
						data1 <= {data1[3:0],data};
					end
			end
	end




//*************code***********//
endmodule

4.VL36 状态机-重叠序列检测

1.题目:

设计一个状态机,用来检测序列 1011,要求:

1、进行重叠检测   即10110111 会被检测通过2次

2、寄存器输出,在序列检测完成下一拍输出检测有效

注意rst为低电平复位


2.解题思路

        2.1 这里为 重复检测,所以 存储数据的寄存器不需要清零。

        2.1 这个的状态机,周期比同步周期 晚了一个时序

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第10张图片


3.解题代码

`timescale 1ns/1ns

module sequence_test2(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);
//*************code***********//
reg[4:0] data1;

always@(posedge clk or rst)
	begin
		if(~rst)
			begin
				data1 <=0;
			end
		else 
			begin
				data1 <= {data1[3:0],data};
			end
	end
always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				flag <=0;
			end
		else
			begin
				if(data1[3:0]== 4'b1011)
					begin
						flag <=1;
					end
				else
					begin
						flag <=0;
					end
			end
	end
//*************code***********//
endmodule

 



5.VL37 时钟分频(偶数)

1.题目:

请使用D触发器设计一个同时输出2/4/8分频的50%占空比的时钟分频器

注意rst为低电平复位

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第11张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第12张图片 

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第13张图片 


2.解题思路

        2.1 首先是 需要一个 记录时序此时 的 计数器。

        2.2 就是注意时序是 同步的 

        2.3 注意这里的  输出类型是  wire  所以时使用  assign 持续赋值语句。

        2.4 注意这个 的输出 先是 1  , 然后是 0.

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第14张图片


3.解题代码

`timescale 1ns/1ns

module even_div
    (
    input     wire rst ,
    input     wire clk_in,
    output    wire clk_out2,
    output    wire clk_out4,
    output    wire clk_out8
    );
//*************code***********//
reg[2:0] cnt ;//计数器
always@(posedge clk_in or negedge rst)
    begin
        if(~rst)
            begin
                cnt <=3'b000;
            end
        else 
            begin
                if(cnt == 3'd000)
                    begin
                        cnt <=3'b111;
                    end
                else
                    begin
                        cnt <= cnt-1'b1;
                    end
            end
    end
assign clk_out2 = (cnt[0]);
assign clk_out4 = (cnt[1]);
assign clk_out8 = (cnt[2]);
//*************code***********//
endmodule

 



6.VL38 自动贩售机1

1.题目:

设计一个自动贩售机,输入货币有三种,为0.5/1/2元,饮料价格是1.5元,要求进行找零,找零只会支付0.5元。

ps:投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号

注意rst为低电平复位

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第15张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第16张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第17张图片


2.解题思路

        2.1 首先是 当零钱的数额大于等于 饮料的价格 时输出 信号。

        2.2 注意找零使用  0.5 元, 所以我们的把价格计录成 0.5 的个数就行了。

        2.3 记得 零钱的数目清零。 因为找零了。

 


3.解题代码

`timescale 1ns/1ns
module seller1(
	input wire clk  ,
	input wire rst  ,
	input wire d1 ,
	input wire d2 ,
	input wire d3 ,
	
	output reg out1,
	output reg [1:0]out2
);
//*************code***********//
reg[3:0] data;//0.5 的个数

always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				data <=0;
			end
		else
		 	begin
				if(d1 == 1'b1)
					begin
						data <= data+1'b1;
					end
				else if(d2 == 1'b1)
					begin
						data <= data + 4'd2; 
					end
				else if(d3 == 1'b1)
					begin
						data <= data + 4'd4;
					end
			end
	end

always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				out1<=0;
				out2<=0;
			end
		else
			begin
				if(data >= 4'd3)
					begin
						out1<=1;
						out2<=data - 4'd3;
						data<=0;
					end
				else
					begin
						out1<=0;
						out2<=0;
					end
			end
	end


//*************code***********//
endmodule


7.VL39 自动贩售机2

1.题目:

 设计一个自动贩售机,输入货币有两种,为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 零钱

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第18张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第19张图片

 


2.解题思路

        

        2.1 首先是 当零钱的数额大于等于 饮料的价格 时输出 信号。

        2.2 注意找零使用  0.5 元, 所以我们的把价格计录成 0.5 的个数就行了。

        2.3 记得 零钱的数目清零。 因为找零了。

        2.4 注意又两种 饮料,所以要判断当时是  买那种饮料。


3.解题代码

`timescale 1ns/1ns

module seller2(
	input wire clk  ,
	input wire rst  ,
	input wire d1 ,
	input wire d2 ,
	input wire sel ,
	
	output reg out1,
	output reg out2,
	output reg out3
);
//*************code***********//
reg[3:0] data;

always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				data <=0;
			end
		else
			begin
				if(d1 == 1'b1)
					begin
						data <= data + 4'd1;
					end
				else if(d2== 1'd1)
					begin
						data <= data +4'd2;
					end
				else
					begin
						data <=data;
					end
			end
	end


always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				out1<=0;
				out2<=0;
				out3<=0;
			end
		else
			begin
				if(sel == 1'b0)
					begin
						if(data >= 4'd3)
							begin
								out1<=1;
								out2<=0;
								out3<=(data - 4'd3);
								data<=0;
							end
						else
							begin
								out1<=0;
								out2<=0;
								out3<=0;
							end
					end
				else if(sel == 1'b1)
					begin
						if(data >= 4'd5)
							begin
								out1<=0;
								out2<=1;
								out3<=(data - 4'd5);
								data<=0;
							end
						else 
							begin
								out1<=0;
								out2<=0;
								out3<=0;
							end
					end
			end
	end



//*************code***********//
endmodule

 



8.VL40 占空比50%的奇数分频

1.题目:

设计一个同时输出7分频的时钟分频器,占空比要求为50%

注意rst为低电平复位

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第20张图片


2.解题思路

        2.1  把他计数成  14   的 ,每 7 个计数, 输出信号变化 。

        2.2 输出信号首先 是0 .

        2.3 注意输出的信号 的类型是 wire  只能使用 assign  持续赋值。

        2.4 同时输出 7个分频哦, 


3.解题代码

`timescale 1ns/1ns

module odo_div_or
   (
    input    wire  rst ,
    input    wire  clk_in,
    output   wire  clk_out7
    );

//*************code***********//
reg[3:0] cnt; //counter

always@(posedge clk_in or negedge rst or negedge clk_in)
    begin
        if(~rst)
            begin
                cnt <=0;
            end
        else 
            begin
                if(cnt == 4'd13)
                    begin
                        cnt <=0 ;
                    end
                else 
                    begin
                        cnt <= cnt + 1;
                    end

            end
    end



assign clk_out7 = (cnt>=7) ? 1 : 0;
//*************code***********//
endmodule

 



9.VL41 任意小数分频

1.题目:

请设计一个可以实现任意小数分频的时钟分频器,比如说8.7分频的时钟信号

注意rst为低电平复位

提示:

其实本质上是一个简单的数学问题,即如何使用最小公倍数得到时钟周期的分别频比。

设小数为nn,此处以8.7倍分频的时钟周期为例。

首先,由于不能在硬件上进行小数的运算(比如2.1个时钟这种是不现实的,也不存在3.3个寄存器),小数分频不能做到分频后每个时钟周期都是源时钟的nn倍,也无法实现占空比为1/2,因此,考虑小数分频,其实现方式应当为53个clkout时钟周期是10个clkin时钟周期的8.7倍。

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第21张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第22张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第23张图片


 

2.解题思路

        2.1  一个分频就是一个周期  所以 这里是 8 个时钟的周期, 或者 9个时钟的周期。

        2.2  给了提示, 前三个是  8分频, 后几个 是 9分频。

        2.3 注意是 输出信号的周期  晚一个时间节点。

        2.4 注意一个 输出信号的类型为  wire .  


3.解题代码

`timescale 1ns/1ns

module div_M_N(
 input  wire clk_in,
 input  wire rst,
 output wire clk_out
);
parameter M_N = 8'd87; 
parameter c89 = 8'd24; // 8/9时钟切换点
parameter div_e = 5'd8; //偶数周期
parameter div_o = 5'd9; //奇数周期
//*************code***********//
reg[7:0] cnt; //counter 
reg clk_out1;
always@(posedge clk_in or negedge rst )
    begin
        if(~rst)
            begin
                cnt <=0;
            end
        else
            begin
                if(cnt == 8'd86)
                    begin
                        cnt <=0;
                    end
                else
                    begin
                        cnt <= cnt +1;
                    end
            end
    end

always@(posedge clk_in or negedge rst)
    begin
        if(~rst)
            begin
                clk_out1 <=0;
            end
        else
            begin
                case(cnt)
                        8'd0 : clk_out1 <= ~clk_out1;
                        8'd4 : clk_out1 <= ~clk_out1;
                        8'd8 : clk_out1 <= ~clk_out1;
                        8'd12: clk_out1 <= ~clk_out1;
                        8'd16: clk_out1 <= ~clk_out1;
                        8'd20: clk_out1 <= ~clk_out1;
                        8'd24: clk_out1 <= ~clk_out1;
                        8'd28: clk_out1 <= ~clk_out1;
                        8'd33: clk_out1 <= ~clk_out1;
                        8'd37: clk_out1 <= ~clk_out1;
                        8'd42: clk_out1 <= ~clk_out1;
                        8'd46: clk_out1 <= ~clk_out1;
                        8'd51: clk_out1 <= ~clk_out1;
                        8'd55: clk_out1 <= ~clk_out1;
                        8'd60: clk_out1 <= ~clk_out1;
                        8'd64: clk_out1 <= ~clk_out1;
                        8'd69: clk_out1 <= ~clk_out1;
                        8'd73: clk_out1 <= ~clk_out1;
                        8'd78: clk_out1 <= ~clk_out1;
                        8'd82: clk_out1 <= ~clk_out1;
                        //'d86: clk_out1 <= ~clk_out1;
                        default : clk_out1 <= clk_out1;
                    endcase
            end
    end

assign clk_out =  clk_out1;  

//*************code***********//
endmodule


10.VL42 无占空比要去的奇数分频

1.0题目:

请设计一个同时输出5分频的时钟分频器,本题对占空比没有要求

注意rst为低电平复位

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第24张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第25张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第26张图片 


2.解题思路

        2.1 计数 器, 每5 个计数 转换输出信号, 只能计数 上升沿,所以第一个变换的时候是在  cnt =0 的时候,第二个是在 cnt = 2 的时候。


3.解题代码

`timescale 1ns/1ns

module odd_div (    
    input     wire rst ,
    input     wire clk_in,
    output    wire clk_out5
);
//*************code***********//
reg[3:0] cnt ;// counter
reg out;

always@(posedge clk_in or negedge rst)
    begin
        if(~rst)
            begin
                cnt <=0;
            end
        else
            begin
                if(cnt == 3'd4)
                    begin
                        cnt <=0;
                    end
                else
                    begin
                        cnt <= cnt +1;
                    end
            end
    end

always@(posedge clk_in or negedge rst)
    begin
        if(~rst)
            begin
                out <=0;
            end
        else
            begin
                if(cnt == 3'd0)
                    begin
                        out <= ~out;
                    end
                else if(cnt == 3'd2)
                    begin
                        out <= ~out; 
                    end
                else
                    begin
                        out <= out;
                    end
            end
    end
assign clk_out5 = out;
//*************code***********//
endmodule

 



11. VL43 根据状态转移写状态机-三段式

1.题目

如图所示为两种状态机中的一种,请根据状态转移图写出代码,状态转移线上的0/0等表示的意思是过程中data/flag的值。

要求:

1、 必须使用对应类型的状态机

2、 使用三段式描述方法,输出判断要求要用到对现态的判断

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第27张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第28张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第29张图片 


2.解题思路

        2.1 三段式状态机

  

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第30张图片 

 


3.解题代码

`timescale 1ns/1ns

module fsm1(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);
//*************code***********//
parameter s0 = 2'd00,
		  s1 = 2'd01,
		  s2 = 2'd10,
		  s3 = 2'd11;
reg[1:0] nextstate,cstate;


always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				cstate <= s0;
			end
		else
			begin
				cstate <= nextstate;
			end
	end

always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				nextstate <=s1;
			end
		else
			begin
				if(nextstate == s0)
					begin
						nextstate <=data ? s1:s0;
					end
				else if(nextstate ==s1)
					begin
						nextstate <=data ? s2:s1;
					end
				else if(nextstate == s2)
					begin
						nextstate <=data ? s3:s2;
					end
				else if(nextstate == s3)
					begin
						nextstate <=data ? s0:s3;
					end
			end
	end
always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				flag <=0;
			end
		else 
			begin
				if(cstate == s3 && data ==1'd1)
					begin
						flag <=1;
					end
				else
					begin
						flag <=0;
					end
			end
	end


//*************code***********//
endmodule



12.VL44 根据状态转移写状态机-二段式

1.题目:

如图所示为两种状态机中的一种,请根据状态转移图写出代码,状态转移线上的0/0等表示的意思是过程中data/flag的值。

要求:

1、 必须使用对应类型的状态机

2、 使用二段式描述方法

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第31张图片

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第32张图片  

   硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第33张图片


2.解题思路

硬件语言Verilog HDL牛客刷题day05时序逻辑部分(2)_第34张图片             2.1.注意三段机 与 二段机的差别 。

             2.2 三段机的次态 的下一个状态  等于  data  和 上一个次态。

             2.3 二段机的次态 的下一个状态  等于  data 和  上一个现态。



 3.解题代码

`timescale 1ns/1ns

module fsm2(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);

//*************code***********//
parameter s0 = 3'd0,
		  s1 = 3'd1,
		  s2 = 3'd2,
		  s3 = 3'd3,
		  s4 = 3'd4;
reg[2:0] nextstate,cstate;


always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				cstate <= s0;
			end
		else
			begin
				cstate <= nextstate;
			end
	end

always@(*)//因为是根据现态来的, 所以是 用的 *  , 上升沿在 cstate变化 的时候可能没有用, 
	begin  //我们这里是要在 cstate 变化之后运行
			case(cstate)
				s0:begin
					nextstate = data ? s1 : s0;
					flag = 1'b0; 
				end
				s1:begin
					nextstate = data ? s2 : s1;
					flag = 1'b0;
				end
				s2:begin
					nextstate = data ? s3 : s2;
					flag = 1'b0;
				end
				s3:begin
					nextstate = data ? s4 : s3;
					flag = 1'b0;
				end
				s4:begin
					nextstate = data ? s1 : s0;
					flag = 1'b1;
				end
				default:begin  
					nextstate = s0;
					flag = 1'b0;             
				end
        	endcase
	end


//*************code***********//
endmodule

 

你可能感兴趣的:(牛客刷题,Verilog,HDL,fpga开发)