关闭

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

标签: 序列检测
265人阅读 评论(0) 收藏 举报
分类:

【温故而知新】【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 TRANSFER
always@(posedge clk or negedge reset) begin
if(!reset)
    current_state   <=  IDLE;
else
    current_state   <=  next_state;
end

//TRANSFER CONDITIONS
always@(*)
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
    end
end                 

//OUTPUT
always@(posedge clk or negedge reset) begin
if(!reset)
    result_out  <=  1'b0;
else if(next_state == S7)
    result_out  <=  1'b1;
    else
    result_out  <=  1'b0;
end

endmodule

测试向量:

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) begin
if(!reset)
    data    <= 8'b00100111;
else if(start_in)
    data    <=  {data[6:0], data[7]};
end 



always@(posedge clk or negedge reset) begin
if(!reset)
    data_in <= 'd0;
else if(start_in)
    data_in <=  data[7];
end 

initial
begin
    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;
end

endmodule

序列检测的状态转换图

image

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

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

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:66624次
    • 积分:1148
    • 等级:
    • 排名:千里之外
    • 原创:56篇
    • 转载:5篇
    • 译文:1篇
    • 评论:12条