用状态机实现序列检测器
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
end
//下降沿检测
always @(posedge clock) begin
if((key_edge[1])&&(cnt2==2'b11)) dat_r[3:0] <= dat_r[3:0] + 1'b1; end
//预置数低 4 位 //下降沿检测
assign rstout = buff[2];
end
言
语
//按键控制处理部分
计
always @(posedge clock)
设
//序列码高 4 位
begin
件 硬
if((key_edge[1])&&(cnt2==2'b00))
//下降沿检测
data[7:4] <= data[7:4] + 1'b1;
end
always @(posedge clock) begin
output[7:0]seg;
//输出接数码管段码
output[7:0]dig;
//输出接数码管位码
//序列码检测模块 I/O 口
output sda; output clkout; output rstout; output[7:0]dat; input[3:0]disp;
reg[7:0]dat_r; reg[7:0]led_r; reg[7:0]seg_r; reg[7:0]dig_r;
buff <= dout1 | dout2 | dout3; end
assign key_edge = ~(dout1 | dout2 | dout3) & buff;
always @(posedge clock)
begin
星
if(key_edge[0]) cnt2 <= cnt2 + 1'b1;
红 袁 —
语//显示 b
4'hc:seg_r = 8'hc6;
计//显示 c
4'hd:seg_r = 8'ha1;
设 //显示 d
硬件 4'he:seg_r = 8'h86;
4'hf:seg_r = 8'h8e;
//显示 e //显示 f
endcase
end
endmodule
模块 2 为:
module schk(sda,clk,rst,dat,disp);
always @(posedge clock)
begin
if (count < 17'd120000)
begin
count <= count + 1'b1;
星
div_clk <= 1'b0; end
红 袁 —
else
言
begin
语
count <= 17'd0;
计
div_clk <= 1'b1;
设
end end
//串行序列码输出
星 //产生时钟信号输出 红 //产生复位信号输出 —袁 //8 位预置数输出 言 //输入检测结果 语 计//输出寄存器 设 件 硬
reg[16:0]count; reg[7:0]data; reg[8:0]data_shift; reg[3:0]dout1,dout2,dout3,buff; reg[2:0]cnt3; reg[1:0]cnt2; reg[3:0]disp_dat; reg div_clk; wire[3:0]key_edge;
5 实验程序
模块 1 为:
module schk_test(clock,key,sda,clkout,rstout,dat,disp,led,seg,dig);
//外接 I/O 口
input clock;
//系统时钟
input[3:0]key;
//按键输入
output[7:0]led;
//输出接 LED
言 码做记忆分析,直到在连续检测中所收到的每一位二进制码都与预置序列码对应相同。在检
语 测过程中,只要有一位不相等都将回到初始状态重新开始检测,不考虑重叠的可能。
设计 (2)为了配合硬件测试,需要设计一个测试模块(schk_test),该模块主要产生序列检测器 件 所需的时钟、复位、串行输入序列码及预置数等信号。
seg[7..0]
数码管段输出
dig[7..0]
数码管位输出
4 实验步骤
(1)启动 Quartus||建立一个空白工程,然后命名为 schk_top.qpf。
(2)新建 VerilogHDL 源程序文件 schk_test(测试信号生成模块),输入程序代码并保存,
将 Verilog HDL 源程序文件转换成图形文件。若在编译过程中发现错误,则找出并更正错误, 直至编译成功为止。 (3)新建 Verilog HDL 源程序文件 schk_v(序列检测模块),输入程序代码并保存,将 Verilog HDL 源程序文件转换成图形文件。若在编译过程中发现错误,则找出并更正错误,直至编 译成功为止。 (4)新建图形设计文件命名为 schk_top.bdf 并保存,其模块原理图如下:
case(disp_dat)
//七段译码
4'h0:seg_r = 8'hc0;
//显示 0
4'h1:seg_r = 8'hf9;
//显示 1
4'h2:seg_r = 8'ha4;
//显示 2
4'h3:seg_r = 8'hb0;
//显示 3
4'h4:seg_r = 8'h99;
//显示 4
4'h5:seg_r = 8'h92;
239
seg[2]
167
dig[1]
159
key[0]ຫໍສະໝຸດ Baidu
121
seg[3]
168
dig[2]
162
key[1]
122
seg[4]
165
dig[3]
161
key[2]
123
seg[5]
166
dig[4]
236
key[3]
124
seg[6]
163
dig[5]
237
clock
28
(6)将 schk_top.bdf 设置为顶层实体,对该工程进行全程编译处理,若在编译过程中发现 错误,则找出错误并更正错误,直至编译成功为止。 (7)硬件连接、下载程序。
硬 对模块的各端口说明如下:
clock
系统时钟输入(48MHz)
key[3..0]
按键输入
disp[3..0]
序列检测器检测结果输入(显示于数码管 8)
sda
串行序列码输出
clkout
序列检测器状态机时钟输出
rstout
序列检测器复位信号输出
dat[7..0]
检测预置数输出
led7..0]
LED 输出
星 //按键 3 复位
assign clkout = buff[3];
红 //按键 4 时钟 袁
—
always @(posedge clock)
言
begin
语
if(key_edge[2])
计 //按键 3 复位
begin
设
硬件 data_shift = {1'b0,data};
led_r = 8'd0;
//重新装载数据
end
else if(key_edge[3])
//按键 4
begin
data_shift = data_shift << 1;
led_r = {data_shift[8],led_r[7:1]}; //LED 左移显示
end
end
assign sda = data_shift[8];
钟;K1~K2 控制输入待检预置数和检测预置数(检测密码),并在数码管 1\2 和 4\5 上显示。
上电时,按 K2 键数码管 1 显示的数累增;按 1 次 K1 后,按 K2 则数码管 2 显示的数累增;
再按 1 次 K1 后,按 K2 则数码管 4 显示的数累增;再按 1 次 K1 后,按 K2 则数码管 5 显示
input
sda;
input
clk;
input
rst;
input[7:0]dat;
//序列检测模块 //串行序列码输入 //时钟信号输入 //复位信号输入
//输入待检测预置数
output[3:0] disp;
//检测结果输出
reg[3:0] disp_r; reg[3:0] state;
//检测结果输出寄存器 //状态机寄存器
红 //选择扫描显示数据 —袁 //第一个数码管
3'd1:disp_dat = data[3:0];
言//第二个数码管
3'd3:disp_dat = dat[7:4];
语//第四个数码管
计 3'd4:disp_dat = dat[3:0]; //第五个数码管
设 3'd7:disp_dat = disp;
//第八个数码管
硬件 default:disp_dat = 4'h0;
endcase
case(cnt3)
//选择数码管显示位
3'd0:dig_r = 8'b01111111;
//选择第一个数码管显示
3'd1:dig_r = 8'b10111111;
//选择第二个数码管显示
3'd3:dig_r = 8'b11101111;
parameter
S0 = 4'd0, S1 = 4'd1, S2 = 4'd2, S3 = 4'd3, S4 = 4'd4, S5 = 4'd5, S6 = 4'd6, S7 = 4'd7, S8 = 4'd8;
//状态机参数
assign disp = disp_r;
//输出检测结果
星
红
always @(posedge clk or negedge rst)
//串行序列码输出
//数码管扫描显示部分 always @(posedge clock) begin
if(div_clk) cnt3 <= cnt3 + 1'b1;
end
//定义上升沿触发进程
always @(posedge clock)
begin
if(div_clk)
begin
星
case(cnt3) 3'd0:disp_dat = data[7:4];
星
红
袁
—
言
语 (5)选择目标器件并对相应的引脚进行定义锁定,在这里所选择的器件为 EP1C12Q240C8
设计 芯片,将未使用的引脚设置为三态输入。引脚分配如下表所示:
信号
引脚
件信号
引脚
信号
引脚
seg[0]
硬 169
seg[7]
164
dig[6]
238
seg[1]
170
dig[0]
160
dig[7]
//显示 5
4'h6:seg_r = 8'h82;
//显示 6
4'h7:seg_r = 8'hf8;
//显示 7
星
4'h8:seg_r = 8'h80; 4'h9:seg_r = 8'h90;
//显示 8
红
—袁 //显示 9
4'ha:seg_r = 8'h88;
言 //显示 a
4'hb:seg_r = 8'h83;
//选择第一个数码管显示
3'd4:dig_r = 8'b11110111;
//选择第二个数码管显示
3'd7:dig_r = 8'b11111110;
//选择第八个数码管显示
default:dig_r = 8'b11111111;
endcase
end
end
always @(disp_dat)
begin
//时钟分频计数器 //内部寄存器
//消抖寄存器 //数码管扫描计数器
//数码管扫描显存 //分频时钟,用于消抖和扫描 //按键消抖输出
assign dat = dat_r; assign led = ~led_r; assign seg = seg_r; assign dig = dig_r;
//时钟分频部分
用状态机实现序列检测器
1 实验目的
掌握利用有限状态机实现一般时序逻辑分析的方法,了解一般状态机的设计与应用。
2 实验内容
设计一序列检测器并在 SmartSOPC 实验箱上进行硬件测试。利用 Quartus ||软件进行设
计、仿真验证,最后进行引脚锁定并完成硬件测试。用 K3 控制复位;K4 控制状态机的时
件 硬
//按键消抖部分 always @(posedge clock) begin
if(div_clk) begin
dout1 <= key; dout2 <= dout1; dout3 <= dout2; end
end
//按键边沿检测部分 always @(posedge clock) begin
if((key_edge[1])&&(cnt2==2'b01)) data[3:0] <= data[3:0] + 1'b1; end
//序列码低 4 位 //下降沿检测
always @(posedge clock)
//预置数高 4 位
begin if((key_edge[1])&&(cnt2==2'b10)) dat_r[7:4] <= dat_r[7:4] + 1'b1;
的数累增;再按 1 次 K1 后,按 K2 则数码管 1 显示的数累增,如此循环。
3 实验原理
星 红 (1)序列检测器可用于检测由二进制码组成的脉冲序列信号。当序列检测器连续收到一组
袁 串行二进制码后,如果这组序列码与检测器中预先设置的序列码相同,则输出 1,否则输出
— 0。这种检测的关键是必须收到连续的正确码,所以要求检测器必须对前一次接受到的序列
袁 —
//下降沿检测
always @(posedge clock) begin
if((key_edge[1])&&(cnt2==2'b11)) dat_r[3:0] <= dat_r[3:0] + 1'b1; end
//预置数低 4 位 //下降沿检测
assign rstout = buff[2];
end
言
语
//按键控制处理部分
计
always @(posedge clock)
设
//序列码高 4 位
begin
件 硬
if((key_edge[1])&&(cnt2==2'b00))
//下降沿检测
data[7:4] <= data[7:4] + 1'b1;
end
always @(posedge clock) begin
output[7:0]seg;
//输出接数码管段码
output[7:0]dig;
//输出接数码管位码
//序列码检测模块 I/O 口
output sda; output clkout; output rstout; output[7:0]dat; input[3:0]disp;
reg[7:0]dat_r; reg[7:0]led_r; reg[7:0]seg_r; reg[7:0]dig_r;
buff <= dout1 | dout2 | dout3; end
assign key_edge = ~(dout1 | dout2 | dout3) & buff;
always @(posedge clock)
begin
星
if(key_edge[0]) cnt2 <= cnt2 + 1'b1;
红 袁 —
语//显示 b
4'hc:seg_r = 8'hc6;
计//显示 c
4'hd:seg_r = 8'ha1;
设 //显示 d
硬件 4'he:seg_r = 8'h86;
4'hf:seg_r = 8'h8e;
//显示 e //显示 f
endcase
end
endmodule
模块 2 为:
module schk(sda,clk,rst,dat,disp);
always @(posedge clock)
begin
if (count < 17'd120000)
begin
count <= count + 1'b1;
星
div_clk <= 1'b0; end
红 袁 —
else
言
begin
语
count <= 17'd0;
计
div_clk <= 1'b1;
设
end end
//串行序列码输出
星 //产生时钟信号输出 红 //产生复位信号输出 —袁 //8 位预置数输出 言 //输入检测结果 语 计//输出寄存器 设 件 硬
reg[16:0]count; reg[7:0]data; reg[8:0]data_shift; reg[3:0]dout1,dout2,dout3,buff; reg[2:0]cnt3; reg[1:0]cnt2; reg[3:0]disp_dat; reg div_clk; wire[3:0]key_edge;
5 实验程序
模块 1 为:
module schk_test(clock,key,sda,clkout,rstout,dat,disp,led,seg,dig);
//外接 I/O 口
input clock;
//系统时钟
input[3:0]key;
//按键输入
output[7:0]led;
//输出接 LED
言 码做记忆分析,直到在连续检测中所收到的每一位二进制码都与预置序列码对应相同。在检
语 测过程中,只要有一位不相等都将回到初始状态重新开始检测,不考虑重叠的可能。
设计 (2)为了配合硬件测试,需要设计一个测试模块(schk_test),该模块主要产生序列检测器 件 所需的时钟、复位、串行输入序列码及预置数等信号。
seg[7..0]
数码管段输出
dig[7..0]
数码管位输出
4 实验步骤
(1)启动 Quartus||建立一个空白工程,然后命名为 schk_top.qpf。
(2)新建 VerilogHDL 源程序文件 schk_test(测试信号生成模块),输入程序代码并保存,
将 Verilog HDL 源程序文件转换成图形文件。若在编译过程中发现错误,则找出并更正错误, 直至编译成功为止。 (3)新建 Verilog HDL 源程序文件 schk_v(序列检测模块),输入程序代码并保存,将 Verilog HDL 源程序文件转换成图形文件。若在编译过程中发现错误,则找出并更正错误,直至编 译成功为止。 (4)新建图形设计文件命名为 schk_top.bdf 并保存,其模块原理图如下:
case(disp_dat)
//七段译码
4'h0:seg_r = 8'hc0;
//显示 0
4'h1:seg_r = 8'hf9;
//显示 1
4'h2:seg_r = 8'ha4;
//显示 2
4'h3:seg_r = 8'hb0;
//显示 3
4'h4:seg_r = 8'h99;
//显示 4
4'h5:seg_r = 8'h92;
239
seg[2]
167
dig[1]
159
key[0]ຫໍສະໝຸດ Baidu
121
seg[3]
168
dig[2]
162
key[1]
122
seg[4]
165
dig[3]
161
key[2]
123
seg[5]
166
dig[4]
236
key[3]
124
seg[6]
163
dig[5]
237
clock
28
(6)将 schk_top.bdf 设置为顶层实体,对该工程进行全程编译处理,若在编译过程中发现 错误,则找出错误并更正错误,直至编译成功为止。 (7)硬件连接、下载程序。
硬 对模块的各端口说明如下:
clock
系统时钟输入(48MHz)
key[3..0]
按键输入
disp[3..0]
序列检测器检测结果输入(显示于数码管 8)
sda
串行序列码输出
clkout
序列检测器状态机时钟输出
rstout
序列检测器复位信号输出
dat[7..0]
检测预置数输出
led7..0]
LED 输出
星 //按键 3 复位
assign clkout = buff[3];
红 //按键 4 时钟 袁
—
always @(posedge clock)
言
begin
语
if(key_edge[2])
计 //按键 3 复位
begin
设
硬件 data_shift = {1'b0,data};
led_r = 8'd0;
//重新装载数据
end
else if(key_edge[3])
//按键 4
begin
data_shift = data_shift << 1;
led_r = {data_shift[8],led_r[7:1]}; //LED 左移显示
end
end
assign sda = data_shift[8];
钟;K1~K2 控制输入待检预置数和检测预置数(检测密码),并在数码管 1\2 和 4\5 上显示。
上电时,按 K2 键数码管 1 显示的数累增;按 1 次 K1 后,按 K2 则数码管 2 显示的数累增;
再按 1 次 K1 后,按 K2 则数码管 4 显示的数累增;再按 1 次 K1 后,按 K2 则数码管 5 显示
input
sda;
input
clk;
input
rst;
input[7:0]dat;
//序列检测模块 //串行序列码输入 //时钟信号输入 //复位信号输入
//输入待检测预置数
output[3:0] disp;
//检测结果输出
reg[3:0] disp_r; reg[3:0] state;
//检测结果输出寄存器 //状态机寄存器
红 //选择扫描显示数据 —袁 //第一个数码管
3'd1:disp_dat = data[3:0];
言//第二个数码管
3'd3:disp_dat = dat[7:4];
语//第四个数码管
计 3'd4:disp_dat = dat[3:0]; //第五个数码管
设 3'd7:disp_dat = disp;
//第八个数码管
硬件 default:disp_dat = 4'h0;
endcase
case(cnt3)
//选择数码管显示位
3'd0:dig_r = 8'b01111111;
//选择第一个数码管显示
3'd1:dig_r = 8'b10111111;
//选择第二个数码管显示
3'd3:dig_r = 8'b11101111;
parameter
S0 = 4'd0, S1 = 4'd1, S2 = 4'd2, S3 = 4'd3, S4 = 4'd4, S5 = 4'd5, S6 = 4'd6, S7 = 4'd7, S8 = 4'd8;
//状态机参数
assign disp = disp_r;
//输出检测结果
星
红
always @(posedge clk or negedge rst)
//串行序列码输出
//数码管扫描显示部分 always @(posedge clock) begin
if(div_clk) cnt3 <= cnt3 + 1'b1;
end
//定义上升沿触发进程
always @(posedge clock)
begin
if(div_clk)
begin
星
case(cnt3) 3'd0:disp_dat = data[7:4];
星
红
袁
—
言
语 (5)选择目标器件并对相应的引脚进行定义锁定,在这里所选择的器件为 EP1C12Q240C8
设计 芯片,将未使用的引脚设置为三态输入。引脚分配如下表所示:
信号
引脚
件信号
引脚
信号
引脚
seg[0]
硬 169
seg[7]
164
dig[6]
238
seg[1]
170
dig[0]
160
dig[7]
//显示 5
4'h6:seg_r = 8'h82;
//显示 6
4'h7:seg_r = 8'hf8;
//显示 7
星
4'h8:seg_r = 8'h80; 4'h9:seg_r = 8'h90;
//显示 8
红
—袁 //显示 9
4'ha:seg_r = 8'h88;
言 //显示 a
4'hb:seg_r = 8'h83;
//选择第一个数码管显示
3'd4:dig_r = 8'b11110111;
//选择第二个数码管显示
3'd7:dig_r = 8'b11111110;
//选择第八个数码管显示
default:dig_r = 8'b11111111;
endcase
end
end
always @(disp_dat)
begin
//时钟分频计数器 //内部寄存器
//消抖寄存器 //数码管扫描计数器
//数码管扫描显存 //分频时钟,用于消抖和扫描 //按键消抖输出
assign dat = dat_r; assign led = ~led_r; assign seg = seg_r; assign dig = dig_r;
//时钟分频部分
用状态机实现序列检测器
1 实验目的
掌握利用有限状态机实现一般时序逻辑分析的方法,了解一般状态机的设计与应用。
2 实验内容
设计一序列检测器并在 SmartSOPC 实验箱上进行硬件测试。利用 Quartus ||软件进行设
计、仿真验证,最后进行引脚锁定并完成硬件测试。用 K3 控制复位;K4 控制状态机的时
件 硬
//按键消抖部分 always @(posedge clock) begin
if(div_clk) begin
dout1 <= key; dout2 <= dout1; dout3 <= dout2; end
end
//按键边沿检测部分 always @(posedge clock) begin
if((key_edge[1])&&(cnt2==2'b01)) data[3:0] <= data[3:0] + 1'b1; end
//序列码低 4 位 //下降沿检测
always @(posedge clock)
//预置数高 4 位
begin if((key_edge[1])&&(cnt2==2'b10)) dat_r[7:4] <= dat_r[7:4] + 1'b1;
的数累增;再按 1 次 K1 后,按 K2 则数码管 1 显示的数累增,如此循环。
3 实验原理
星 红 (1)序列检测器可用于检测由二进制码组成的脉冲序列信号。当序列检测器连续收到一组
袁 串行二进制码后,如果这组序列码与检测器中预先设置的序列码相同,则输出 1,否则输出
— 0。这种检测的关键是必须收到连续的正确码,所以要求检测器必须对前一次接受到的序列
袁 —