【温故而知新】【4】Verilog序列检测

来源:互联网 发布:淘宝客退款还算佣金吗 编辑:程序博客网 时间:2024/06/05 06:02

【温故而知新】【4】Verilog序列检测


seuchenrui@126.com

11/21/2015 2:21:04 PM

本次博客的内容是回顾状态机的的编写。状态机的经典描述方式为三段式描述。这三段分别为:

状态转移(时序逻辑)–> 状态变换条件(组合逻辑)–> 输出逻辑(组合逻辑或者时序逻辑)。

下文为一个序列检测的状态机代码,可持续检测序列“00100111”。

代码:

`timescale 1ns / 1ns//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer:  //      seuchenrui@126.com// Create Date:09:31:28 11/21/2015 // Design Name: // Module Name:sequence_00100111 // Project Name: // Target Devices: // Tool versions: // Description: //  this is the module for check sequence "00100111"// Dependencies: //// Revision: // Revision 0.01 - File Created// Usage of asynchronous resets may negatively impact FPGA resources// and timing. In general faster and smaller FPGA designs will// result from not using asynchronous resets. Please refer to// the Synthesis and Simulation Design Guide for more information.      // Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module sequence_00100111    (                        clk_in,                        reset,                        enable_in,                        data_in,                        start_in,                        result_out                                          );parameter       IDLE    =   8'b0000_0000;parameter       S0      =   8'b0000_0001;   parameter       S1      =   8'b0000_0010;   parameter       S2      =   8'b0000_0100;   parameter       S3      =   8'b0000_1000;   parameter       S4      =   8'b0001_0000;   parameter       S5      =   8'b0010_0000;   parameter       S6      =   8'b0100_0000;   parameter       S7      =   8'b1000_0000;   //-----------------------//  DEFINE I/O//-----------------------           input   clk_in;input   reset;input   enable_in;input   data_in;input   start_in;output  result_out;//------------------------//  DEFINE SIGNAL//------------------------ reg         result_out;reg [7:0]   next_state;reg [7:0]   current_state;//------------------------//  MAIN CODE//------------------------ assign  clk =   enable_in & clk_in;//STATE TRANSFERalways@(posedge clk or negedge reset) beginif(!reset)    current_state   <=  IDLE;else    current_state   <=  next_state;end//TRANSFER CONDITIONSalways@(*)begin    next_state = IDLE;    if(enable_in) begin        case(current_state)            IDLE:                   if(start_in )                    next_state  =   S0;                else                    next_state  =   IDLE;            S0: if(data_in == 1'b1)         //0                    next_state  =   S0;                else                    next_state  =   S1;            S1: if(data_in == 1'b1)         //00                    next_state  =   S2;                else                    next_state  =   S1;            S2: if(data_in == 1'b1)         //001                    next_state  =   S0;                else                    next_state  =   S3;            S3: if(data_in == 1'b1)         //0010                    next_state  =   S0;                else                    next_state  =   S4;            S4: if(data_in == 1'b1)         //00100                    next_state  =   S5;                else                    next_state  =   S1;            S5: if(data_in == 1'b1)         //001001                    next_state  =   S6;                else                    next_state  =   S3;                                                     S6: if(data_in == 1'b1)         //0010011                    next_state  =   S7;                else                    next_state  =   S0;                     S7:                         //00100111                    next_state  =   S0;            default:                        next_state  =   IDLE;           endcase    endend                 //OUTPUTalways@(posedge clk or negedge reset) beginif(!reset)    result_out  <=  1'b0;else if(next_state == S7)    result_out  <=  1'b1;    else    result_out  <=  1'b0;endendmodule

测试向量:

module testbench();reg clk;reg reset;reg data_in;reg enable_in;reg start_in;wire    result_out;reg [7:0]   data;sequence_00100111   uut (                        .clk_in(clk),                        .reset(reset),                        .enable_in(enable_in),                        .data_in(data_in),                        .start_in(start_in),                        .result_out(result_out)                                         );always #5 clk = ~clk;//assign    data    =   8'b00100111;always@(posedge clk or negedge reset) beginif(!reset)    data    <= 8'b00100111;else if(start_in)    data    <=  {data[6:0], data[7]};end always@(posedge clk or negedge reset) beginif(!reset)    data_in <= 'd0;else if(start_in)    data_in <=  data[7];end initialbegin    clk = 0;    reset = 0;    start_in = 0;    enable_in = 0;    #77;    reset = 1;    enable_in = 1;    #55;    start_in = 1;    #500;    enable_in = 0;    #500;    $finish;endendmodule

序列检测的状态转换图

image

XILINX ISIM仿真波形图-1
这里写图片描述

XILINX ISIM仿真波形图-2
这里写图片描述

0 0
原创粉丝点击