5.4 -1 序列检测器拓展(FPGA-quartus-仿真步骤)


前言

提示:本篇仅为个人学习笔记,如有错误欢迎斧正
本篇以教材习题moore型的序列检测器为例


数字电路与程序设计

一、5.4 -1 序列检测器拓展

在例5.3和例5.4序列检测器的基础上,增加当收到的脉冲序列数据为0时,则记录后八位数据的功能。

二、FPGA-quartus-仿真步骤

1.项目建立

这里我们以此题为例街上FPGA-quartus-仿真步骤:

源码如下:

module  seq_det_moore
(
	input   clk , reset,
	input   din,
	output reg [7:0] data=0,//8位寄存器
	output reg [7:0] data_out,//输出
	output reg[ 2:0 ] cs , 
	output reg[ 2:0 ] nst ,
	output reg[3:0] n ,
	output reg sout
) ;
	//  状态声明
	localparam[ 2:0 ]//局部参数 声明常量
		s0 = 3'b000 ,
		s1 = 3'b001 ,
		s2 = 3'b010 ,
		s3 = 3'b011 ,
		s4 = 3'b100 ,
		s5 = 3'b101 ;//存数据操作
		//	reg[ 2:0 ] cs , nst ;  //我这里注释是以为我在上面ouput了 因为我想在仿真里面看见我的参数值
//	reg[3:0] n ;
initial
begin
cs=s0;
nst=s0;
data=0;
sout=0;
n=0;
end	
	//状态更新
	always@ (posedge clk , posedge reset )
	begin
		if ( reset )
		begin
			cs <= s0 ;
		end
		else
		begin
			cs <= nst ;
		end
	end
	//S5计数模块 clk上升沿
	always@(posedge clk)
		begin
			if((nst==s5)&&(n!=4'b1000))
				begin
					if(din == 1'b1 )
					begin
						data=data<<1;
						data=data+1;
						n=n+1;
						
					end
					else
					begin
						data=data<<1;
						n=n+1;
						
					end
				end
		end
   //状态迁移
	always  @*
	begin
		case  (cs)
			s0:
				if (din == 1'b1 ) 
				begin
					nst = s1 ;
				end
            else 
				begin
					nst = s0 ;
				end
			s1:
				if (din == 1'b1 ) 
				begin
					nst = s2 ;
				end
            else 
				begin
					nst = s0 ;
				end
			s2:
				if (din == 1'b0 ) 
				begin
					nst = s3 ;
				end
            else 
				begin
					nst = s0  ;
				end
			s3:
				if (din == 1'b1 ) 
				begin
					nst = s4;
				end
            else 
				begin
					nst = s0 ;
				end
			s4:
				if (din == 1'b0 )
				begin
					nst = s5 ;
				end
            else 
				begin
					nst = s0;
				end
			s5:
				begin
					if(n!=4'b1000)
					begin
						nst = s5;
					end
					else
					begin
						nst= s0;
					end
				end
			default : 
				nst = s0 ;
		endcase
	end                   
	
	//输出
	always  @*
	begin
		if (cs == s4)
		begin
			sout = 1;
		end
		else 
		begin
			sout = 0;
		end
		//输出
		if ((cs == s5)&&(n==4'b1000))
			begin
			data_out = data;
			end
	end
endmodule

首先我们需要写入.v文件
首先在file-new里面创立.v文件 写入你的程序
在file-new里面
然后保存文件!记得复制这个文件名要用哦
在这里插入图片描述
ctrl+s 选择你中意的文件路径 建议一个项目一个文件夹哦 然后把这个文件保存道文件夹里
在这里插入图片描述
然后他会提示你是否创建一个新项目 我们选择yes!
连点四下next出现 我们选择cyclone V se mainstream 和 5F31C6 我用的板子的型号

在这里插入图片描述
下一步这样选 然后finish
在这里插入图片描述

2.vt文件的建立与路径设置

首先我们点这个 创立vt文件
在这里插入图片描述
再 file-open再对应路径下 simulation-modelsim
在这里插入图片描述
这里我们要点这个才会看见vt文件
在这里插入图片描述
open之后我们就可以在里面写东西啦~~~

vt文件我是这样写的(写的很垃圾 嘿嘿):

`timescale 1 ps/ 1 ps  //设置单位时间以及最小精度
module seq_det_moore_vlg_tst();//下面是一些参数的预处理吧
reg eachvec;
reg clk;
reg din;
reg reset;
// wires                                               
wire [2:0]  cs;
wire [7:0]  data;
wire [7:0]  data_out;
wire [3:0]  n;
wire [2:0]  nst;
wire sout;

// assign statements (if any)                          
seq_det_moore i1 (
// port map - connection between master ports and signals/registers   
	.clk(clk),
	.cs(cs),
	.data(data),
	.data_out(data_out),
	.din(din),
	.n(n),
	.nst(nst),
	.reset(reset),
	.sout(sout)
);
initial        //这个模块只执行一次                                         
begin
clk=1;                                                  
reset = 1;
din=0;
#2 reset = 0;


#2 din = 1;
#2 din = 1;
#2 din = 0;
#2 din = 1;

#2 din = 0;

#2 din = 1;
#2 din = 1;
#2 din = 1;
#2 din = 0;
#2 din = 1;
#2 din = 0;
#2 din = 1;
#2 din = 0;

#2 din = 0;
#2 din = 0;
#2 din = 0;
#50 $stop;           //这里设定延时50停止运行                                    
$display("Running testbench");                       
end
                                                    
always        //这个模块一直运行 我们这里设好clk 时钟信号                                                          
begin                                                  
#1 clk = ~clk;                                                                                                              
end                                                    
endmodule

写好之后我们复制这个文件名
在这里插入图片描述
crtl+shift+e打开setting 在simulation 里面打开Test Benches
在这里插入图片描述
点new 把我们刚刚复制的文件名粘贴上去
再点击file name旁边的三个点
在这里插入图片描述

打开我们的vt文件,这样我们的vt文件和v文件的连接就建立好了
在这里插入图片描述
记住点add
在这里插入图片描述
然后一路ok下去 然后点击这里仿真
在这里插入图片描述
nice仿真成功啦 点一下wave 和那个 放大镜一样的东西就可以清晰看见仿真了

在这里插入图片描述

三、序列检测器拓展

1. 实例

题目要求是在1101 的基础上接受道0的脉冲 然后记录后八位数吧
我就用注释讲一下题目思路

module  seq_det_moore
(
	input   clk , reset, //clk是时钟信号 reset 重置状态
	input   din,         //脉冲序列
	output reg [7:0] data=0,//8位寄存器
	output reg [7:0] data_out,//输出
	output reg[ 2:0 ] cs , //当前状态
	output reg[ 2:0 ] nst ,//下一状态
	output reg[3:0] n , //八位计数的计数器 (确保我只记录八位数)
	output reg sout  //1101监测成功的一个信号
) ;
	//  状态声明
	localparam[ 2:0 ]//局部参数 声明常量
		//设定五种状态 后面的值只是为了好区分 并没有实际含义
		s0 = 3'b000 , 
		s1 = 3'b001 ,
		s2 = 3'b010 ,
		s3 = 3'b011 ,
		s4 = 3'b100 ,
		s5 = 3'b101 ;//存数据操作
		//	reg[ 2:0 ] cs , nst ;  //我这里注释是以为我在上面ouput了 因为我想在仿真里面看见我的参数值
//	reg[3:0] n ;
initial //在这里设置初值否则仿真可能会出现不知名的错误 (血的教训)
begin
cs=s0;
nst=s0;
data=0;
sout=0;
n=0;
end	
	//状态更新模块
	always@ (posedge clk , posedge reset ) //clk的上升沿触发
	begin
		if ( reset )
		begin
			cs <= s0 ;
		end
		else
		begin
			cs <= nst ;
		end
	end
	//S5计数模块 clk上升沿 
	//这里我把计数模块单独写了出来
	always@(posedge clk)
		begin
			if((nst==s5)&&(n!=4'b1000))
				begin
					if(din == 1'b1 )
					begin
					//这里用了一个很有趣的计数方法 我称其为移位计数
					//你用笔演示一次就可以看见是怎么记录的01信号的
						data=data<<1;
						data=data+1;
						n=n+1;		
					end
					else
					begin
						data=data<<1;
						n=n+1;
					end
				end
		end
   //状态迁移
   //下面就是状态机的内容了 这个没必要赘述
	always  @*
	begin
		case  (cs)
			s0:
				if (din == 1'b1 ) 
				begin
					nst = s1 ;
				end
            else 
				begin
					nst = s0 ;
				end
			s1:
				if (din == 1'b1 ) 
				begin
					nst = s2 ;
				end
            else 
				begin
					nst = s0 ;
				end
			s2:
				if (din == 1'b0 ) 
				begin
					nst = s3 ;
				end
            else 
				begin
					nst = s0  ;
				end
			s3:
				if (din == 1'b1 ) 
				begin
					nst = s4;
				end
            else 
				begin
					nst = s0 ;
				end
			s4:
				if (din == 1'b0 )
				begin
					nst = s5 ;
				end
            else 
				begin
					nst = s0;
				end
			s5:
				begin
					//当n=8的时候说明我八位数记满了
					if(n!=4'b1000)
					begin
						nst = s5;
					end
					else
					begin
						nst= s0;
					end
				end
			default : 
				nst = s0 ;
		endcase
	end                   
	
	//输出
	always  @*
	begin
		if (cs == s4)//s4监测到1101的信号
		begin
			sout = 1;
		end
		else 
		begin
			sout = 0;
		end
		//输出
		if ((cs == s5)&&(n==4'b1000))
			begin
			//这里data满8为 将data_out作为输出 输出
			data_out = data;
			end
	end
endmodule

2. Moore Mealy型

Moore

if (cs == s4)
begin
sout = 1;
end
else 
begin
sout = 0;
end

Mealy

if(cs==s3)&&(din==1'b1)
begin
sout=1;
end
else
begin
sout=0;
end

其实很明显我们发现Mealy只是多了以个din值的限定
就是说Mealy型的输出与当前脉冲序列有关,当这个脉冲序列一变,sout就会变。
而Moore只是与我们的状态有关。
(理解的很浅显)


如果写的有什么不对的,希望大佬提出来。
  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值