刷题:牛客刷题-进阶挑战篇

前言

正文

牛客刷题链接

一、序列检测

VL25 输入序列连续的序列检测

要求:请编写一个序列检测模块,检测输入信号a是否满足01110001序列,当信号满足该序列,给出指示信号match。

方法:
方法一使用状态机,需要注意状态在不满足跳转的情况下,跳到哪里去
在这里插入图片描述
方法二:使用序列缓存对比,通过移位+拼接对输入信号a进行缓存,缓存完成后和目标序列进行比较

//VL25 输入序列连续的序列检测
//方法一:使用状态机======================================
`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);
	
	parameter S0 = 'b0,
			  S1 = 'b01,
			  S2 = 'b011,
			  S3 = 'b0111,
			  S4 = 'b0111_0,
			  S5 = 'b0111_00,
			  S6 = 'b0111_000,
			  S7 = 'b0111_0001;
	reg [7:0] state;
	reg [7:0] next_state;
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			state <= S0;
		end
		else 
			state <= next_state;
	end
	
	always@(*)begin
		case(state)
			S0: next_state = (a)?S1:S0;
			S1: next_state = (a)?S2:S0;
			S2: next_state = (a)?S3:S0;
			S3: next_state = (~a)?S4:S0;
			S4: next_state = (~a)?S5:S1;
			S5: next_state = (~a)?S6:S1;
			S6: next_state = (a)?S7:S1;
			S7: next_state = S0;
		default:next_state = S0;
		endcase
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			match <= 1'd0;
		end
		else if((state== S7))begin
			match <= 1'd1;
		end
		else
			match <= 1'd0;
	end
endmodule

//方法二:使用序列缓存对比======================================
`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);
	
	reg [7:0] a_reg;
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			a_reg <= 8'd0;
		end
		else 
			a_reg <= {a_reg[6:0],a};
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			match <= 1'd0;
		end
		else if(a_reg == 8'b0111_0001)begin
			match <= 1'd1;
		end
		else
			match <= 1'd0;
	end
	
endmodule

VL26 含有无关项的序列检测

最初我看到无关项,第一反应使用casez表示哪些无关项,于是有了下面的错误

//VL26 含有无关项的序列检测

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);
	
	parameter S0 = 'b0,
			  S1 = 'b01,
			  S2 = 'b011,
			  S3 = 'b011?,
			  S4 = 'b011?_?,
			  S5 = 'b011?_??,
			  S6 = 'b011?_??1,
			  S7 = 'b011?_??11,
			  S8 = 'b011?_??110;
	reg [8:0] state;
	reg [8:0] next_state;
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			state <= S0;
		end
		else 
			state <= next_state;
	end
	
	always@(*)begin
		casez(state)
			S0: next_state = (a)?S1:S0;
			S1: next_state = (a)?S2:S0;
			S2: next_state = S3;
			S3: next_state = S4;
			S4: next_state = S5;
			S5: next_state = (a)?S6:S0;
			S6: next_state = (a)?S7:S0;
			S7: next_state = (~a)?S8:S0;
			S8: next_state = S0;
		default:next_state = S0;
		endcase
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			match <= 1'd0;
		end
		else if((state == S7) && (a == 1'd0))begin
			match <= 1'd1;
		end
		else
			match <= 1'd0;
	end
endmodule

仿真就会发现,状态部分是高阻态,及时到了S8,也不会将match拉高
在这里插入图片描述
还是用移位寄存的方法:(正确

//VL26 含有无关项的序列检测

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);	
	
	reg [8:0] a_reg;
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			a_reg <= 9'd0;
		end
		else 
			a_reg <= {a_reg[7:0],a};
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )
			match <= 1'd0;
		else begin
			casez(a_reg)
				9'b011?_??110: match <= 1'd1;
			default:match <= 1'd0;
			
			endcase
		end
	end
	
endmodule

VL28 输入序列不连续的序列检测

题目描述:

请编写一个序列检测模块,输入信号端口为data,表示数据有效的指示信号端口为data_valid。当data_valid信号为高时,表示此刻的输入信号data有效,参与序列检测;当data_valid为低时,data无效,抛弃该时刻的输入。当输入序列的有效信号满足0110时,拉高序列匹配信号match
在这里插入图片描述

//VL28 输入序列不连续的序列检测

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input data,
	input data_valid,
	output   match
	);
	
	parameter S0 = 'b0,
			  S1 = 'b01,
			  S2 = 'b011,
			  S3 = 'b0110;
	
	reg [3:0] state;
	reg [3:0] next_state;
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			state <= S0;
		end
		else 
			state <= next_state;
	end
	
	always@(*)begin
		case(state)
			S0: 
				if(data_valid && data)
					next_state = S1;
				else
					next_state = S0;
			S1:
				if(data_valid && data)
					next_state = S2;
				else
					next_state = S0;			
			S2: 
				if(data_valid && (~data))
					next_state = S3;
				else
					next_state = S0;			
			S3: next_state = S0;
		default:next_state = S0;
		endcase						
	
	end
	assign match = (state == S3)?1'd1:1'd0;
/* 	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			match <= 1'd0;
		end
		else if(state == S3)begin
			match <= 1'd1;
		end
		else
			match <= 1'd0;
	end  */
endmodule

VL29 信号发生器

这道题我没有运行出来,但是在modelsim中运行出来了,可以参考评论区的答案: 评论区答案

//状态机方法
`timescale 1ns/1ns
module signal_generator(
	input clk,
	input rst_n,
	input [1:0] wave_choise,
	output reg [4:0]wave
	);
	
//==========================================parameter===========================================================
	parameter CNT_MAX = 12'd19;
	parameter S0 = 'd0,
			  S1 = 'd1,
			  S2 = 'd2;

//==========================================reg=================================================================
	reg [2:0] state;
	reg [2:0] next_state;
	
	reg [11:0] cnt_1249;
	reg [11:0] cnt_san;	
	
	reg up  ;
	reg down;
//==========================================wire=================================================================
	wire flage_9;
	wire flage_19;
//==========================================assign=================================================================
	assign flage_9 = (cnt_1249 == 'd9) ?1'd1:1'd0;
	assign flage_19 = (cnt_1249 == 'd19)?1'd1:1'd0;
//==========================================always=================================================================
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			cnt_san <= 'd0;
		end
		else if(up)begin
			cnt_san <= cnt_san + 'd1;
		end
		else if(down)begin
			cnt_san <= cnt_san - 'd1;
			if(cnt_san == 'd0)
				cnt_san <= cnt_san;
		end
		else if((state == S1)&&(next_state == S2))
			cnt_san <= 'd0;
		else
			cnt_san <= cnt_san;

	end
	
	//assign cnt_1249 = (cnt_1249 == CNT_MAX)? 12'd0 : (cnt_1249 + 12'd1);
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			cnt_1249 <= 'd0;
		end
		else if((cnt_1249 == CNT_MAX) ||((state == S0)&&(next_state == S1)) ||((state == S1)&&(next_state == S2)) ||((state == S2)&&(next_state == S0)))begin
			cnt_1249 <=  'd0;
		end
		else
			cnt_1249 <= cnt_1249 + 12'd1;
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			up   <= 1'd0;
			down <= 1'd0;
		end
		else if(cnt_san == CNT_MAX-1)begin
			up   <= 1'd0;
			down <= 1'd1;		
		end
		else if(cnt_san == 'd0)begin
			up   <= 1'd1;
			down <= 1'd0;		
		end
		else begin
			up   <= up;
			down <= down;		
		end
			
	end
	
//==========================================状态机=================================================================
always@(posedge clk or negedge rst_n)begin
	if(!rst_n )begin
		state <= S0;
	end
	else 
		state <= next_state;
end

always@(*)begin
	case(state)
		S0:
			if(wave_choise == 'd1)
				next_state = S1;
			else
				next_state = S0;
		S1:
			if(wave_choise == 'd2)
				next_state = S2;
			else
				next_state = S1;		
		S2:
			if(wave_choise == 'd0)
				next_state = S0;
			else
				next_state = S2;	
	default:next_state = S0;
	endcase
end

always@(posedge clk or negedge rst_n)begin
	if(!rst_n )begin
		wave <= 'd0;
	end
	else if((state == S0) && (flage_9))
		wave <= 'd20;
	else if((state == S0) && (flage_19))
		wave <= 'd0;
	else if((state == S0) && (~flage_19) && (~flage_9))
		wave <= wave;
	//锯齿波
	else if((state == S1) && (cnt_1249 < 'd19))
		wave <= wave + 'd1;
	else if((state == S1) && (cnt_1249 == 'd19))
		wave <= 'd0;
	//三角波
	else if((state == S2) && (cnt_san == 'd0))
		wave <= 'd0;
	else if(up)
		wave <= wave + 'd1;
	else if(down)begin
		wave <= wave - 'd1;
		if(wave == 'd0)
			wave <= wave;
	end
	else
		wave <= wave;
end
	
endmodule


在这里插入图片描述

VL30 数据串转并电路

分析:

  1. data_b
  • 什么时候改变:计数器计到5时才更新,且保持不变直到下一次更新
  • 变成什么值:将cnt=5上升沿瞬间的data_a和data_b_reg[5:1]拼接即可(如果直接将data_b_reg打一拍赋值给data_b,那么cnt=5那一瞬间的值data_a就漏采了)
  1. valid_b:
  • 什么时候改变:cnt=5拉高(cnt=5末尾处拉高)
  • 其余时刻保持低电平
    在这里插入图片描述
    在这里插入图片描述
`timescale 1ns/1ns
module s_to_p(
	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
);
reg [5:0] data_b_reg;
reg [3:0] cnt_6;

always @(posedge clk or negedge rst_n ) begin
	if(!rst_n) 
		ready_a <= 'd0;
	else 
		ready_a <= 1'd1;
end

always@(posedge clk or negedge rst_n)begin
	if(!rst_n )begin
		cnt_6 <= 4'd0;
	end
    else if(cnt_6 == 'd5)
        cnt_6 <= 4'd0;
	else if(valid_a && ready_a)begin
		cnt_6 <= cnt_6 + 4'd1;
	end		
end

always@(posedge clk or negedge rst_n)begin
	if(!rst_n )begin
		data_b_reg <= 6'd0;
	end
	else if(valid_a)begin
		data_b_reg <= {data_a,data_b_reg[5:1]};
	end
	else
		data_b_reg <= data_b_reg;
end

always@(posedge clk or negedge rst_n)begin
	if(!rst_n )begin
		valid_b <= 1'd0;
	end
	else if((cnt_6 == 'd5)&& valid_a)begin
		valid_b <= 1'd1;
	end
	else
		valid_b <= 1'd0;
end

always@(posedge clk or negedge rst_n)begin
	if(!rst_n )
        data_b = 'd0;                          
	else if(cnt_6 == 'd5)
		data_b = {data_a,data_b_reg[5:1]};//将当前输入和寄存的值拼接,若果直接将寄存的值赋值给左边,会延迟一拍,会漏掉一个数据
	else
		data_b = data_b;
end

endmodule

二、时序逻辑

三、跨时钟域传输

四、计数器

五、存储器

六、综合

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值