博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

捕获数据中的某个序列---verilog

Posted on 2019-02-26 10:57  沉默改良者  阅读(554)  评论(0编辑  收藏  举报

捕获数据中的某个序列---verilog

状态变化图

先是检测序列,每当接收到cmp_equal信号时跳转到下一个状态,等待另外一个cmp_equal信号到来。

代码:

always @ *
    case(current_state)
        STATE_START:
            if (cmp_equal)
                next_state = STATE_ADF2;
            else
                next_state = STATE_START;            //每当检测不到cmp_equal信号时,状态就跳转到STATE_START
                
        STATE_ADF2:
            if (cmp_equal)
                next_state = STATE_ADF3;
            else
                next_state = STATE_START;           //同上

        STATE_ADF3:
            if (cmp_equal)
                next_state = STATE_DID;
            else
                next_state = STATE_START;          //同上

        STATE_DID:
            if (cmp_equal)
                next_state = STATE_SDID;
            else
                next_state = STATE_START;         //同上

        STATE_SDID:
            if (cmp_equal)
                next_state = STATE_DC;
            else
                next_state = STATE_START;        //同上

        STATE_DC:
            if (cmp_equal)
                next_state = STATE_UDW0;
            else
                next_state = STATE_START;        //同上

        STATE_UDW0:
            next_state = STATE_UDW1;             //解出所需要的数据

        STATE_UDW1:
            next_state = STATE_UDW2;             //解数据

        STATE_UDW2:
            next_state = STATE_UDW3;             //解数据

        STATE_UDW3:
            next_state = STATE_CS;               

        STATE_CS:
            next_state = STATE_START;

        default:    next_state = STATE_START;
    endcase

状态机状态调转模块采用的是组合逻辑。

always @ (posedge clk or posedge rst)
    if (rst)
        current_state <= STATE_START;
    else if (ce)
        current_state <= next_state;

状态输出模块:

always @ *
    begin
        // Unless specifically assigned in the case statement, all FSM outputs
        // are given the values assigned here.
        ld_byte1    = 1'b0;                      //数据解码使能信号
        ld_byte2    = 1'b0;
        ld_byte3    = 1'b0;
        ld_byte4    = 1'b0;
        ld_cs_err   = 1'b0;
        clr_cs      = 1'b0;
        cmp_mux_sel = MUX_SEL_000;              //数据比对选择信号
                                
        case(current_state) 

            STATE_START:    clr_cs = 1'b1;   //此状态比对的就是 000数据

            STATE_ADF2:     begin
                                cmp_mux_sel = MUX_SEL_3FF; //此状态比对的就是 3FF数据
                                clr_cs = 1'b1;
                            end

            STATE_ADF3:     begin
                                cmp_mux_sel = MUX_SEL_3FF;  // 比对3FF
                                clr_cs = 1'b1;
                            end

            STATE_DID:      cmp_mux_sel = MUX_SEL_DID;       //比对DID数据

            STATE_SDID:     cmp_mux_sel = MUX_SEL_SDID;      //比对SDID数据

            STATE_DC:       cmp_mux_sel = MUX_SEL_DC;        //比对DC数据

            STATE_UDW0:     ld_byte1 = 1'b1;                 //数据解码使能

            STATE_UDW1:     ld_byte2 = 1'b1;

            STATE_UDW2:     ld_byte3 = 1'b1;

            STATE_UDW3:     ld_byte4 = 1'b1;

            STATE_CS:       begin
                                cmp_mux_sel = MUX_SEL_CS;   //比对数据CS
                                ld_cs_err = 1'b1;
                            end
        endcase
    end

cmp_equal信号产生与数据比对模块生成代码:

always @ *                                //组合逻辑
    case(cmp_mux_sel)
        MUX_SEL_000:    cmp_mux = 10'h000;
        MUX_SEL_3FF:    cmp_mux = 10'h3ff;
        MUX_SEL_DID:    cmp_mux = 10'h241;
        MUX_SEL_SDID:   cmp_mux = 10'h101;
        MUX_SEL_DC:     cmp_mux = 10'h104;
        MUX_SEL_CS:     cmp_mux = {~checksum[8], checksum};
        default:        cmp_mux = 10'h000;
    endcase

assign cmp_equal = cmp_mux == vid_in;            //实时监控vid_in数据,当符合条件时,产生cmp_equal信号
localparam [MUXSEL_MSB:0]
    MUX_SEL_000     = 0,
    MUX_SEL_3FF     = 1,
    MUX_SEL_DID     = 2,
    MUX_SEL_SDID    = 3,
    MUX_SEL_DC      = 4,
    MUX_SEL_CS      = 5;