Verilog實現BCD碼到余3碼轉換器


本例把一個串行發送的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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM