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