本例把一個串行發送的BCD碼轉換位一個余3碼串行比特流。
將BCD碼對應的十進制數加上3,再轉化為等效的二進制數就得到了該十進制數的余3碼。同時余3碼是自補碼,即余3碼的“9的補數”在硬件上可以通過對碼字逐位取反得到。
Mealy型FSM實現是通過每一位數字來了之后是否向下一位進位來實現的。初始狀態用S_0表示。
通過該例應該學會使用FSM的狀態轉換圖(STG)輔助設計
/*顯式狀態機推薦使用兩個行為來描述,一個邊沿敏感行為用於同步狀態轉移, * 另一個電平敏感行為用於描述下一個狀態和輸出邏輯 */ /*在描述顯示狀態機的下一個狀態和輸出的組合邏輯的電平敏感行為時, * 要對所有可能的狀態譯碼*/ module BCD_to_Express_3b( output reg B_out, input B_in, clk, reset_b); parameter S_0=3'b000, S_1=3'b001, S_2=3'b101, S_3=3'b111, S_4=3'b011, S_5=3'b110, S_6=3'b010, dont_care_state=3'bx; reg[2:0] state, next_state; always @(posedge clk,negedge reset_b) if(reset_b==0) state<=S_0; else state<=next_state; always @(state, B_in) begin B_out=0; case(state) S_0: if(B_in)begin next_state=S_1; B_out=0; end else begin next_state=S_2; B_out=1; end S_1:begin next_state=S_3; B_out=B_in; end S_2: if(B_in)begin next_state=S_3; B_out=0; end else begin next_state=S_4; B_out=1; end S_3: if(B_in)begin next_state=S_6; B_out=0; end else begin next_state=S_5; B_out=1; end S_4:begin next_state=S_5; B_out=B_in; end S_5:begin next_state=S_0; B_out=B_in; end S_6:begin next_state=S_0; B_out=!B_in; end /*default:begin next_state=S_0; B_out=0; end*/ endcase end endmodule
測試代碼如下,分別順序傳入0~9,其中count1表示1~9,count2表示count1的位數
`timescale 1ns/1ps module BCD_to_Express_3b_tb; reg clk,reset_b; wire B_in; wire B_out; reg[3:0] count1; reg[1:0] count2; initial begin clk=0; reset_b=1; count1=0; count2=0; #15 reset_b=0; #5 reset_b=1; #5000 $finish; end initial begin $dumpfile("dump.lxt"); $dumpvars(0,BCD_to_Express_3b_tb); end always #10 clk=!clk; always @(posedge clk)begin count2=count2+1; end always @(negedge clk) if(count2==2'b11) count1=count1+1; always @(negedge reset_b)begin count2=0; count1=0; end assign B_in=count1[count2]; BCD_to_Express_3b uut( .B_out(B_out), .B_in(B_in), .clk(clk), .reset_b(reset_b) ); endmodule