【Verilog学习日常】—牛客网刷题—Verilog企业真题—VL62

序列发生器

描述

编写一个模块,实现循环输出序列001011

模块的接口信号图如下:

要求使用Verilog HDL实现,并编写testbench验证模块的功能。

输入描述:

clk:时钟信号

rst_n:复位信号,低电平有效

输出描述:

data:输出数据

解题思路

序列信号发生器设计步骤如下:

①确定寄存器的个数n;

由于M(序列信号的长度)= 6,所以n≥3;接下来

②确定寄存器的六个独立状态;

将序列码001011按照移位规律每三位一组,可划分为六个状态**:001、010、101、011、110、100**;

③列态序表和反馈激励函数表;

态序表

|-----------------------------------------------|-----------------------------------------------------------|
| | |
| 001 | 010 |
| 010 | 101 |
| 101 | 011 |
| 011 | 110 |
| 110 | 100 |
| 100 | 001 |
| 000 | 001 |
| 111 | 110 |

反馈激励函数表

|-----------------------------------|-----------------------------------|-----------------------------------|---------------------------------|
| | | | |
| 0 | 0 | 1 | 0 |
| 0 | 1 | 0 | 1 |
| 1 | 0 | 1 | 1 |
| 0 | 1 | 1 | 0 |
| 1 | 1 | 0 | 0 |
| 1 | 0 | 0 | 1 |

将态序表的每下一状态 所需要的移位(左移)输入作为该状态对应的反馈函数输出

即:

根据反馈激励函数表,画卡诺图

当设计最终的序列输出时,我们发现最后的输出序列为状态Q0的值(因为每次从Q0端移出数据) ;因此

④列出三大方程

状态方程

特征方程(注意:该题的Q0Q1Q2有初始值,若不设置初始值(如错误代码所示),结果错误)

输出方程

因此,我们给出了以下两种代码方式;

代码一:例化触发器

cpp 复制代码
`timescale 1ns/1ns
//输出序列:"001011"
module sequence_generator(
	input clk,
	input rst_n,
	output reg data
	);

	wire d0, d1, d2;
	wire q0, q1, q2;

	assign d0 = q1;
	assign d1 = q2;
	assign d2 = ~q0&~q2 | q0&~q1;

	DFF D0(.d({d2,d1,d0}), .clk(clk), .rst_n(rst_n), .q({q2,q1,q0}));

	always @(posedge clk or negedge rst_n) begin
		if (!rst_n) data <= 1'b0;
		else 	data <= q0;
	end

endmodule

//例化D触发器
module DFF (
	input	[2:0] 		d,
	input 		clk,
	input 		rst_n,
	output reg [2:0]	q
);
	always @(posedge clk or negedge rst_n) begin
		if (!rst_n)	q[2:0] = 3'b100;
		else q[2:0] = d[2:0];
	end

endmodule

代码二: 不例化触发器

cpp 复制代码
`timescale 1ns/1ns
//输出序列:"001011"
module sequence_generator(
	input clk,
	input rst_n,
	output reg data
	);

	reg q0, q1, q2;

	always @(posedge clk or negedge rst_n) begin
		if (!rst_n)	begin
			q0 <= 1'b0;
			q1 <= 1'b0;
			q2 <= 1'b1;
		end
		else  begin
			q0 <= q1;
			q1 <= q2;
			q2 <= ~q0&~q2 | q0&~q1;
		end
	end

	always @(posedge clk or negedge rst_n) begin
		if (!rst_n) data <= 1'b0;
		else 	data <= q0;
	end

endmodule

错误代码:(即未考虑Q0、Q1、Q2的初始值)

将Q0、Q1、Q2均使用带复位端的D触发器例化;

cpp 复制代码
`timescale 1ns/1ns
//输出序列:"001011"
module sequence_generator(
	input clk,
	input rst_n,
	output reg data
	);

	wire F;
	wire d0, d1, d2;
	wire q0, q1, q2;

	assign d0 = q1;
	assign d1 = q2;
	assign d2 = ~q0&q1&~q2 | q0&~q1;

	DFF D0(.d(d0), .clk(clk), .rst_n(rst_n), .q(q0));
	DFF D1(.d(d1), .clk(clk), .rst_n(rst_n), .q(q1));
	DFF D2(.d(d2), .clk(clk), .rst_n(rst_n), .q(q2));

	always @(posedge clk or negedge rst_n) begin
		if (!rst_n) data <= 1'b0;
		else 	data <= q0;
	end

endmodule

//例化D触发器
module DFF (
	input 		d,
	input 		clk,
	input 		rst_n,
	output	reg	q
);
	always @(posedge clk or negedge rst_n) begin
		if (!rst_n)	q = 1'b0;
		else q = d;
	end

endmodule

我们再给出一种解法,使用有限状态机

解法二:有限状态机

注意:此处将IDLE注释掉,结果仍然正确。

cpp 复制代码
`timescale 1ns/1ns
//输出序列:"001011"
module sequence_generator(
	input clk,
	input rst_n,
	output reg data
	);
//代码三
	reg [2:0] current_state, next_state;

	parameter IDLE = 3'b000;
	parameter S1 = 3'b001;
	parameter S2 = 3'b010;
	parameter S3 = 3'b101;
	parameter S4 = 3'b011;
	parameter S5 = 3'b110;
	parameter S6 = 3'b100;

	always @(posedge clk or negedge rst_n) begin
		if (!rst_n) current_state <= IDLE;
		else	current_state <= next_state;
	end

	always @(*) begin
		case (current_state)
		IDLE:begin next_state = S1;	data <= 1'b0; end
		S1: begin  next_state = S2; data <= 1'b0; end
		S2: begin  next_state = S3; data <= 1'b0; end
		S3: begin  next_state = S4; data <= 1'b1; end
		S4: begin  next_state = S5; data <= 1'b0; end
		S5: begin  next_state = S6; data <= 1'b1; end
		S6: begin  next_state = S1; data <= 1'b1; end
		default: begin next_state = S1; data <= 1'b0; end
		endcase
	end
endmodule
相关推荐
-一杯为品-9 分钟前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
风尚云网1 小时前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
EterNity_TiMe_2 小时前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
sanguine__3 小时前
java学习-集合
学习
lxlyhwl3 小时前
【STK学习】part2-星座-目标可见性与覆盖性分析
学习
nbsaas-boot3 小时前
如何利用ChatGPT加速开发与学习:以BPMN编辑器为例
学习·chatgpt·编辑器
CV学术叫叫兽3 小时前
一站式学习:害虫识别与分类图像分割
学习·分类·数据挖掘
我们的五年3 小时前
【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数
linux·c++·学习
一棵开花的树,枝芽无限靠近你4 小时前
【PPTist】添加PPT模版
前端·学习·编辑器·html
VertexGeek4 小时前
Rust学习(八):异常处理和宏编程:
学习·算法·rust