状态机序列检测器vlog.doc_第1页
状态机序列检测器vlog.doc_第2页
状态机序列检测器vlog.doc_第3页
状态机序列检测器vlog.doc_第4页
状态机序列检测器vlog.doc_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一、 实验目的掌握利用有限状态机实现一般时序逻辑分析的方法,了解一般状态机的设计与应用。二、 实验内容设计一序列检测器并在SmartSOPC实验箱上进行硬件测试。利用Quartus |软件进行设计、仿真验证,最后进行引脚锁定并完成硬件测试。用KEY5控制复位,KEY6控制状态机的时钟,KEY1KEY4控制输入待检预置数和检测预置数(检测密码),并在数码管12和45上显示。三、 实验原理(1)序列检测器可用于检测由二进制码组成的脉冲序列信号。当序列检测器连续收到一组串行二进制码后,如果这组序列码与检测器中预先设置的序列码相同,则输出1,否则输出0.这种检测的关键是必须收到连续的正确码,所以要求检测器必须对前一次接受到的序列码做记忆分析,直到在连续检测中所收到的每一位二进制码都与预置序列码对应相同。在检测过程中,只要有一位不相等都将回到初始状态重新开始检测。不考虑重叠的可能。(2)为了配合硬件测试,本实验提供了一个测试模块(schk_test),该模块主要产生序列检测器所需的时钟、复位、串行输入序列码及预置数等信号。对莫模块的各端口说明如下:Clock系统时钟输入(48MHz)key5.0 按键输入disp3.0 序列检测器检测结果输入(显示于数码管8)sda 串行序列码输出clkout序列检测器状态机时钟输出rstout 序列检测器复位信号输出dat7.0 检测预置数输出led7.0 LED输出seg7.0 数码管段输出dig7.0 数码管位输出四、实验步骤(1)启动Quartus|建立一个空白工程,然后命名为schk_top.qpf。(2)新建VerilogHDL源程序文件schk_v,输入程序代码并保存,进行综合编译。若在编译过程中发现错误,则找出并更正错误,直至编译成功为止。(3)将光盘中的EDA_Component目录下的schk_test.bsf,schk_test.v拷贝到工程目录。(原理图形式需此步骤)(4)新建图形设计文件命名为schk_top.bdf并保存,其模块原理图如下:(5)选择目标器件并对相应的引脚进行定义锁定,在这里所选择的器件为EPIC6Q240C8芯片,将未使用的引脚设置为三态输入。(6)将schk_top.bdf设置为顶层实体,对该工程进行全程编译处理,若在编译过程中发现错误,则找出错误并更正错误,直至编译成功为止。(7)硬件连接、下载程序。五、实验程序(一)原理图形式的实验参考程序如下:模块1为:moduleschk(sda,clk,rst,dat,disp);/序列检测器模块inputsda;/串行序列码输入inputclk;/时钟信号输入inputrst;/复位信号输入input7:0dat;/输入待检测预置数output3:0disp;/检测结果输出reg3:0disp_r;/检测结果输出寄存器reg3:0state;/状态机寄存器parameters0=4d0,s1=4d1,/状态机参数s2=4d2,s3=4d3,s4=4d4,s5=4d5,s6=4d6,s7=4d7,s8=4d8;assigndisp=disp_r;/输出检测结果always(posedge clk or negedge rst)beginif(rst)state=s0;/复位elsebegincase(state)s0:if(sda=dat7)state=s1;else state=s0;/状态s0s1:if(sda=dat6)state=s2;else state=s0;/状态s1s2:if(sda=dat5)state=s3;else state=s0;/状态s2s3:if(sda=dat4)state=s4;else state=s0;/状态s3s4:if(sda=dat3)state=s5;else state=s0;/状态s4s5:if(sda=dat2)state=s6;else state=s0;/状态s5s6:if(sda=dat1)state=s7;else state=s0;/状态s6s7:if(sda=dat0)state=s8;else state=s0;/状态s7default:state=s0;endcaseendendalways (state)beginif(state=s8)disp_r=4hf;/序列码检测正确,输出“F”elsedisp_r=4h0;/序列码检测错误,输出“0”endendmodule模块2为:module schk_test(clock,key,sda,clkout,rstout,dat,disp,led,seg,dig); /外接I/O口 input clock;/系统时钟 input5:0key;/按键输入 output7:0led;/输出接LED output7:0seg;/输出接数码管段码 output7:0dig;/输出接数码管位码 /序列码检测模块I/O口 output sda;/串行序列码输出 output clkout;/产生时钟信号输出 output rstout;/产生复位信号输出 output7:0dat;/8位预置数输出 input3:0disp;/输入检测结果 reg7:0dat_r;/输出寄存器 reg7:0led_r; reg7:0seg_r; reg7:0dig_r; reg16:0count;/时钟分频计数器 reg7:0data;/内部寄存器 reg8:0data_shift; reg5:0dout1,dout2,dout3,buff;/消抖寄存器 reg2:0cnt3; /数码管扫描计数器 reg3:0disp_dat; /数码管扫描显存 reg div_clk;/分频时钟,用于消抖和扫描 wire5:0key_edge;/按键消抖输出 assign dat = dat_r; assign led = led_r; assign seg = seg_r; assign dig = dig_r; /时钟分频部分 always (posedge clock) begin if (count 17d120000) begin count = count + 1b1; div_clk = 1b0; end else begin count = 17d0; div_clk = 1b1; end end /按键消抖部分 always (posedge clock) begin if(div_clk) begin dout1 = key; dout2 = dout1; dout3 = dout2; end end /按键边沿检测部分 always (posedge clock) begin buff = dout1 | dout2 | dout3; end assign key_edge = (dout1 | dout2 | dout3) & buff; /按键控制处理部分 always (posedge clock)/按键1 序列码高4位 begin if(key_edge0)/下降沿检测 data7:4 = data7:4 + 1b1; end always (posedge clock)/按键2 序列码低4位 begin if(key_edge1)/下降沿检测 data3:0 = data3:0 + 1b1; end always (posedge clock)/按键3 预置数高4位 begin if(key_edge2)/下降沿检测 dat_r7:4 = dat_r7:4 + 1b1; end always (posedge clock)/按键4 预置数低4位 begin if(key_edge3)/下降沿检测 dat_r3:0 = dat_r3:0 + 1b1; end assign rstout = buff4;/按键5 复位 assign clkout = buff5;/按键6 时钟 always (posedge clock) begin if(key_edge4)/按键5 复位 begin data_shift = 1b0,data;/重新装载数据 led_r = 8d0; end else if(key_edge5)/按键6 begin data_shift = data_shift 1; led_r = data_shift8,led_r7:1;/LED左移显示 end end assign sda = data_shift8;/串行序列码输出 /数码管扫描显示部分 always (posedge clock) /定义上升沿触发进程 begin if(div_clk) cnt3 = cnt3 + 1b1; end always (posedge clock) begin if(div_clk) begin case(cnt3)/选择扫描显示数据 3d0:disp_dat = data7:4;/第一个数码管 3d1:disp_dat = data3:0;/第二个数码管 3d3:disp_dat = dat7:4;/第四个数码管 3d4:disp_dat = dat3:0;/第五个数码管 3d7:disp_dat = disp;/第八个数码管 default:disp_dat = 4h0; endcase case(cnt3)/选择数码管显示位 3d0:dig_r = 8b01111111;/选择第一个数码管显示 3d1:dig_r = 8b10111111;/选择第二个数码管显示 3d3:dig_r = 8b11101111;/选择第四个数码管显示 3d4:dig_r = 8b11110111;/选择第五个数码管显示 3d7:dig_r = 8b11111110;/选择第八个数码管显示 default:dig_r = 8b11111111; endcase end end always (disp_dat) begin case(disp_dat)/七段译码 4h0:seg_r = 8hc0;/显示0 4h1:seg_r = 8hf9;/显示1 4h2:seg_r = 8ha4;/显示2 4h3:seg_r = 8hb0;/显示3 4h4:seg_r = 8h99;/显示4 4h5:seg_r = 8h92;/显示5 4h6:seg_r = 8h82;/显示6 4h7:seg_r = 8hf8;/显示7 4h8:seg_r = 8h80;/显示8 4h9:seg_r = 8h90;/显示9 4ha:seg_r = 8h88;/显示a 4hb:seg_r = 8h83;/显示b 4hc:seg_r = 8hc6;/显示c 4hd:seg_r = 8ha1;/显示d 4he:seg_r = 8h86;/显示e 4hf:seg_r = 8h8e;/显示f endcase end endmodule(二)用程序形式做的程序如下;module schk(clock,key,sda,clkout,dat,disp,led,seg,dig); /外接I/O口 input clock;/系统时钟 input5:0key;/按键输入 /inputsda;/串行序列码输入wirerst;/复位信号输入/input3:0disp;/输入检测结果 /input7:0dat;/输入待检测预置数output7:0led;/输出接LED output7:0seg;/输出接数码管段码 output7:0dig;/输出接数码管位码 output sda;/串行序列码输出 output clkout;/产生时钟信号输出 output7:0dat;/8位预置数输出 output3:0disp;/检测结果输出reg7:0dat_r;/输出寄存器 reg7:0led_r; reg7:0seg_r; reg7:0dig_r; reg16:0count;/时钟分频计数器 reg7:0data;/内部寄存器 reg8:0data_shift; reg5:0dout1,dout2,dout3,buff;/消抖寄存器 reg2:0cnt3; /数码管扫描计数器 reg3:0disp_dat; /数码管扫描显存 reg div_clk;/分频时钟,用于消抖和扫描 reg3:0disp_r;/检测结果输出寄存器reg3:0state;/状态机寄存器wire5:0key_edge;/按键消抖输出 assign dat = dat_r; assign led = led_r; assign seg = seg_r; assign dig = dig_r; parameters0=4d0,s1=4d1,/状态机参数s2=4d2,s3=4d3,s4=4d4,s5=4d5,s6=4d6,s7=4d7,s8=4d8;assigndisp=disp_r;/输出检测结果/时钟分频部分 always (posedge clock) begin if (count 17d120000) begin count = count + 1b1; div_clk = 1b0; end else begin count = 17d0; div_clk = 1b1; end end /按键消抖部分 always (posedge clock) begin if(div_clk) begin dout1 = key; dout2 = dout1; dout3 = dout2; end end /按键边沿检测部分 always (posedge clock) begin buff = dout1 | dout2 | dout3; end assign key_edge = (dout1 | dout2 | dout3) & buff; /按键控制处理部分 always (posedge clock)/按键1 序列码高4位 begin if(key_edge0)/下降沿检测 data7:4 = data7:4 + 1b1; end always (posedge clock)/按键2 序列码低4位 begin if(key_edge1)/下降沿检测 data3:0 = data3:0 + 1b1; end always (posedge clock)/按键3 预置数高4位 begin if(key_edge2)/下降沿检测 dat_r7:4 = dat_r7:4 + 1b1; end always (posedge clock)/按键4 预置数低4位 begin if(key_edge3)/下降沿检测 dat_r3:0 = dat_r3:0 + 1b1; end assign rst = buff4;/按键5 复位 assign clkout = buff5;/按键6 时钟 always (posedge clock) begin if(key_edge4)/按键5 复位 begin data_shift = 1b0,data;/重新装载数据 led_r = 8d0; end else if(key_edge5)/按键6 begin data_shift = data_shift 1; led_r = data_shift8,led_r7:1;/LED左移显示 end endassign sda = data_shift8;/串行序列码输出 /数码管扫描显示部分 always (posedge clock) /定义上升沿触发进程 begin if(div_clk) cnt3 = cnt3 + 1b1; end always(negedge key_edge5 or negedge rst)beginif(rst)state=s0;/复位elsebegincase(state)s0:if(sda=dat7)state=s1;else state=s0;/状态s0s1:if(sda=dat6)state=s2;else state=s0;/状态s1s2:if(sda=dat5)state=s3;else state=s0;/状态s2s3:if(sda=dat4)state=s4;else state=s0;/状态s3s4:if(sda=dat3)state=s5;else state=s0;/状态s4s5:if(sda=dat2)state=s6;else state=s0;/状态s5s6:if(sda=dat1)state=s7;else state=s0;/状态s6s7:if(sda=dat0)state=s8;else state=s0;/状态s7default:state=s0;endcaseendendalways (posedge clock) begin if(div_clk) begin case(cnt3)/选择扫描显示数据 3d0:disp_dat = data7:4;/第一个数码管 3d1:disp_dat = data3:0;/第二个数码管 3d3:disp_dat = dat7:4;/第四个数码管 3d4:disp_dat = dat3:0;/第五个数码管 3d7:disp_dat

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论