差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
序列检测器 [2016/06/10 14:32] anran [硬件平台] |
序列检测器 [2016/06/12 11:16] anran [代码设计] |
||
---|---|---|---|
行 10: | 行 10: | ||
- 掌握序列检测的原理 | - 掌握序列检测的原理 | ||
- 掌握状态机的设计 | - 掌握状态机的设计 | ||
- | - 基于[[STEP-Baseboard]]平台实现101序列的检测 | + | - 基于[[STEP-MXO2第一代]]平台实现101序列的检测 |
====工作原理==== | ====工作原理==== | ||
行 28: | 行 28: | ||
====硬件连接==== | ====硬件连接==== | ||
------ | ------ | ||
- | 为了方便我们在硬件平台上更直观的观察,我们的序列检测的信号输入和检测时钟都采用[[STEP-Baseboard]]平台上的拨码开关S2和S1实现,序列检测的结果我们用[[STEP-MXO2第一代]]平台上的LED灯LD1输出指示。 | + | 为了方便我们在硬件平台上更直观的观察,我们使用25MHz时钟晶振分频产生1Hz的信号作为序列检测的时钟,同时使用LED灯LD1指示1Hz信号,按键信号作为序列检测的信号输入,LED灯LD2作为序列检测的输出指示。 |
- | {{ :图11.拨码模块电路连接.png |拨码模块电路连接}} | + | {{ :按键硬件图.jpg |按键硬件图}} |
{{ :led电路连接.jpg |LED电路连接}} | {{ :led电路连接.jpg |LED电路连接}} | ||
- | |||
====代码设计==== | ====代码设计==== | ||
行 41: | 行 40: | ||
{{ :序列检测状态转移图.jpg |序列检测状态转移图}} | {{ :序列检测状态转移图.jpg |序列检测状态转移图}} | ||
+ | 为了得到1Hz的信号,我们设计了25位的计数器cnt进行0.5s周期的循环计数,同时clk_1hz信号进行翻转,这样就得到了序列检测的时钟信号,然后再以序列检测的时钟信号为触发条件进行状态机的控制最终实现序列检测。 | ||
- | + | 首先是计数器的设计,计数器的计数范围为0~CNT_NUM-1,设计文件代码中我们定义参数CNT_NUM为12500000,但是在仿真文件调用设计文件时,为了方便仿真,我们会将参数CNT_NUM重新赋值为5. | |
- | + | ||
- | + | ||
- | {{ :流水灯程序设计.jpg |流水灯程序设计}} | + | |
- | + | ||
- | 为了实现对8个LED的控制,我们设计了25位的计数器cnt进行1s周期的循环计数,同时我们定义了一个4位寄存器led_cnt作为状态机的状态控制流水灯的闪烁。状态机共有8个状态,每一个状态对应点亮一个LED灯。 | + | |
- | + | ||
- | 首先是计数器的设计,计数器的计数范围为0~CNT_NUM-1,为了实现每个LED灯1秒的点亮时间,设计文件代码中我们定义参数CNT_NUM为25000000,但是在仿真文件调用设计文件时,为了方便仿真,我们会将参数CNT_NUM重新赋值为10. | + | |
<code verilog> | <code verilog> | ||
reg [24:0] cnt = 25'd0; | reg [24:0] cnt = 25'd0; | ||
- | always@(posedge clk_in or negedge rst_n_in) begin | + | always@(posedge clk or negedge rst_n) begin |
- | if(!rst_n_in) begin | + | if(!rst_n) begin |
cnt <= 25'd0; | cnt <= 25'd0; | ||
- | end else if(cnt>=CNT_NUM-1) begin | + | clk_1hz <= 1'b0; |
+ | end else if(cnt>=(CNT_NUM-1)) begin | ||
cnt <= 25'd0; | cnt <= 25'd0; | ||
+ | clk_1hz <= ~clk_1hz; | ||
end else begin | end else begin | ||
cnt <= cnt + 25'd1; | cnt <= cnt + 25'd1; | ||
行 64: | 行 59: | ||
</code> | </code> | ||
- | 然后我们需要对状态机的状态进行控制,使得作为状态的寄存器led_cnt实现从0到7的循环加一操作。 | + | 然后按照状态机的状态转移图实现状态机的设计。 |
<code verilog> | <code verilog> | ||
- | reg [3:0] led_cnt = 4'd0; | + | reg[1:0]state; |
- | always@(posedge clk_in or negedge rst_n_in) begin | + | always @(posedge clk_1hz or negedge rst_n) begin |
- | if(!rst_n_in) begin | + | if(!rst_n) begin |
- | led_cnt <= 4'd0; | + | state<=s0; |
- | end else if(cnt==CNT_NUM-1) begin | + | vout<=0; |
- | if(led_cnt==4'd7) led_cnt <= 4'd0; | + | end else case(state) |
- | else led_cnt <= led_cnt + 4'd1; | + | s0: begin |
- | end | + | if(vin==0) begin state<=s0;vout<=0; end |
+ | else begin state<=s1;vout<=0; end | ||
+ | end | ||
+ | s1: begin | ||
+ | if(vin==0) begin state<=s2;vout<=0; end | ||
+ | else begin state<=s1;vout<=0; end | ||
+ | end | ||
+ | s2: begin | ||
+ | if(vin==0) begin state<=s0;vout<=0; end | ||
+ | else begin state<=s1;vout<=1; end | ||
+ | end | ||
+ | default:state<=s0; | ||
+ | endcase | ||
end | end | ||
</code> | </code> | ||
- | 最后是组合逻辑,根据led_cnt的不同状态控制不同的LED点亮。 | + | 我们在设计中将序列检测的时钟信号设计为1Hz,并且使用LED指示序列检测的时钟信号的变化,方便在板子上按键及观察输出的情况。 |
- | + | ||
- | <code verilog> | + | |
- | always@(led_cnt) begin | + | |
- | case(led_cnt) | + | |
- | 4'd0: led_out = 8'b1111_1110; | + | |
- | 4'd1: led_out = 8'b1111_1101; | + | |
- | 4'd2: led_out = 8'b1111_1011; | + | |
- | 4'd3: led_out = 8'b1111_0111; | + | |
- | 4'd4: led_out = 8'b1110_1111; | + | |
- | 4'd5: led_out = 8'b1101_1111; | + | |
- | 4'd6: led_out = 8'b1011_1111; | + | |
- | 4'd7: led_out = 8'b0111_1111; | + | |
- | default: led_out = 8'b1111_1111; | + | |
- | endcase | + | |
- | end | + | |
- | </code> | + | |
===测试文件=== | ===测试文件=== | ||
- | 测试文件中我们需要对设计文件中的参数CNT_NUM进行重新赋值 | + | 测试文件中我们需要对设计文件中的参数CNT_NUM进行重新赋值,同时对vin信号每400ns(序列检测时钟 = 系统时钟周期*分配系数*2 = 40*5*2 = 400ns)间隔取随机值。 |
<code verilog> | <code verilog> | ||
- | parameter CNT_NUM = 10; | + | always vin = # 400 $random; |
- | Water_led #(.CNT_NUM(CNT_NUM)) | + | |
- | Water_led_uut | + | wire clk_1hz,vout; |
+ | Serial_Detect # | ||
+ | ( | ||
+ | .CNT_NUM(CNT_NUM) | ||
+ | ) | ||
+ | Serial_Detect_uut | ||
( | ( | ||
- | .clk_in(sys_clk), | + | .clk(sys_clk), |
- | .rst_n_in(sys_rst_n), | + | .rst_n(sys_rst_n), |
- | .led_out(led_out) | + | .vin(vin), |
+ | .clk_1hz(clk_1hz), | ||
+ | .vout(vout) | ||
); | ); | ||
</code> | </code> | ||
行 113: | 行 111: | ||
引脚分配如下: | 引脚分配如下: | ||
- | ^ 管脚名称 | clk_in| rst_n_in | led_out[0] |led_out[1] |led_out[2] |led_out[3] |led_out[4] |led_out[5] |led_out[6] |led_out[7] | | + | ^ 管脚名称 | clk| rst_n | vin |clk_1hz |vout | |
- | ^ FPGA管脚 | C1 | A2 |B14 |C14 |E14 |F14 |G14 |J14 |K14 |L14 | | + | ^ FPGA管脚 | C1 | A2 |B7 |A3 |A7 | |
====仿真结果==== | ====仿真结果==== | ||
- | {{:流水灯仿真.jpg|流水灯仿真}} | + | {{:序列检测仿真.jpg|序列检测仿真}} |
====资源报告==== | ====资源报告==== | ||
^ 资源 | 数量 | 比例 | 说明 | | ^ 资源 | 数量 | 比例 | 说明 | | ||
- | ^ LUTs | 28 | 4% | | | + | ^ LUTs | 39 | 3% | | |
- | ^ 寄存器 | 33 | 2% | | | + | ^ 寄存器 | 28 | 2% | | |
^ 存储器 | 0 | 0% | | | ^ 存储器 | 0 | 0% | | | ||
- | ^ IO管脚 | 10 | | | | + | ^ IO管脚 | 5 | | | |
^ 时钟频率 | 25MHz | | | | ^ 时钟频率 | 25MHz | | | | ||
行 135: | 行 133: | ||
====参考文档==== | ====参考文档==== | ||
- | * [[点亮led灯]] | ||
* {{:machxo2familydatasheet.pdf|Lattice MachXO2数据手册}} | * {{:machxo2familydatasheet.pdf|Lattice MachXO2数据手册}} | ||
行 142: | 行 139: | ||
^ **文件名称** | **功能** | | ^ **文件名称** | **功能** | | ||
- | ^ **[[Water_led.v]]** | **流水灯** | | + | ^ **[[Serial_Detect.v]]** | **流水灯** | |
- | ^ **[[Water_led_test.v]]** | **测试文件** | | + | ^ **[[Serial_Detect_test.v]]** | **测试文件** | |