捕獲數據中的某個序列---verilogless
狀態變化圖spa
先是檢測序列,每當接收到cmp_equal信號時跳轉到下一個狀態,等待另一個cmp_equal信號到來。code
代碼:blog
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
狀態機狀態調轉模塊採用的是組合邏輯。ci
always @ (posedge clk or posedge rst) if (rst) current_state <= STATE_START; else if (ce) current_state <= next_state;
狀態輸出模塊:class
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;