Verilog上機實驗(一):BCD碼交替顯示控制器

摸摸頭_發表於2020-06-29

實驗要求*

第一步:

首先設計一個Binary-to-BCD譯碼器(二進位制數轉換成十進位制數)模組:
它有4bit 輸入:
SW3,SW2,SW1,SW0(在實驗中如果嫌麻煩可以直接使用reg [3:0] SW 陣列進行代替)
例如:
若輸入組合為:
“1111”,則X7~X0輸出為:“00010101”
其次設計一個BCD-to-7-segment譯碼器模組:
它有4bit輸入:
X3,X2,X1,X0,
7bit輸出:
A,B,C,D,E,F,G 用於控制LED display 的七段
7端字母的對應關係如下:
在這裡插入圖片描述
在這裡插入圖片描述

第二步:

設計一個BCD交替顯示控制模組:
將它與第一步的兩個實驗相結合,實現Binary-to-BCD的交替顯示控制功能:
將撥位開關SW7~SW0代表的8位二進位制數轉換成三位的Hrs,Tens,Ones,並驅動多個數碼管顯示,其中SegSel用於控制哪個數碼管的顯示
在這裡插入圖片描述

使用器件:

xc7a35tcpg236-1

使用軟體:

vivado

在這裡插入圖片描述

vivado工作介面

在這裡插入圖片描述

工程結構

在這裡插入圖片描述

綜合結果

在這裡插入圖片描述

多工器

在這裡插入圖片描述

重新整理電路

在這裡插入圖片描述

BCD譯碼器

如下圖相同結構的八層迭代
在這裡插入圖片描述

模擬結果

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

命令列輸出

在這裡插入圖片描述

實驗效果

在這裡插入圖片描述

核心程式碼:

頂層模組程式碼:

module Top_Module(
    input Clk,
    input SW7,
    input SW6,
    input SW5,
    input SW4,
    input SW3,
    input SW2,
    input SW1,
    input SW0,
    output A,
    output B,
    output C,
    output D,
    output E,
    output F,
    output G,
    output [3:0]SegSel_n
    );
    wire [7:0]SW;
    wire [3:0]Hrs;
    wire [3:0]Tens;
    wire [3:0]Ones;
    wire [3:0]Dval;
    wire [6:0]L;
    wire [3:0]SegSel;
    assign SW={SW7,SW6,SW5,SW4,SW3,SW2,SW1,SW0};
    Refresh R1(.Clk(Clk),.Rst(1'b0),.SegSel(SegSel));
    binary_to_BCD B1(.SW(SW),.Hrs(Hrs),.Tens(Tens),.Ones(Ones));
    MUX M1(.Refresh(SegSel),.Dval(Dval),.Hrs(Hrs),.Tens(Tens),.Ones(Ones));
    
    
    
    BCD_to_7_segment S1(.X(Dval),.Lights(L));
    assign {A,B,C,D,E,F,G}=~L;
    assign SegSel_n=~SegSel;
endmodule

重新整理電路模組程式碼:

module Refresh(Clk,Rst,SegSel

    );
    input Clk,Rst;
    output reg [3:0]SegSel;
    initial begin
    SegSel=4'b0001;
    end
    reg [7:0] count_fst;
    reg[3:0]count_second;
    always@(posedge Clk)begin
        if(Rst==1) begin
            count_fst<=8'b00000000;
            SegSel<=4'b0000;
        end
        else begin
            if(count_fst==8'b11111111)
                begin
                count_fst<=4'b00000000;
                count_second<=count_second+1'b1;
                if(count_second==4'b1111)begin
                count_second<=4'b0000;
                case(SegSel)
                    4'b0000:SegSel<=4'b0001;
                    4'b0001:SegSel<=4'b0010;
                    4'b0010:SegSel<=4'b0100;
                    4'b0100:SegSel<=4'b1000;
                    4'b1000:SegSel<=4'b0001;
                    default:SegSel<=4'b0000;
                endcase
            end
            end
            else count_fst<=count_fst+8'b00000001;
        end
    end
endmodule


binary-to-BCD模組程式碼:

module binary_to_BCD(SW,Hrs,Tens,Ones);
    input [7:0] SW;
    output [3:0]Hrs;
    output [3:0]Tens;
    output [3:0]Ones;
    reg [17:0] Z;
    always@(SW)begin
    Z=18'b0;
    Z[7:0]=SW;
    repeat(8)
    begin
    if(Z[11:8]>4)
        Z[11:8]=Z[11:8]+2'b11;
    if(Z[15:12]>4)
        Z[15:12]=Z[15:12]+2'b11;
    Z[17:1]=Z[16:0];
    end
    
    end
    assign Hrs=Z[17:16];
    assign Tens=Z[15:12];
    assign Ones=Z[11:8];
           
endmodule

多工器模組程式碼:

module MUX(Refresh,Dval,Hrs,Tens,Ones

    );
    input [3:0] Refresh;
    input [3:0]Tens;
    input [3:0]Hrs;
    input [3:0]Ones;
    output reg [3:0]Dval;
    always@(*) begin
    case(Refresh)
        4'b0000:Dval=4'b0000;
        4'b0001:Dval=Ones;
        4'b0010:Dval=Tens;
        4'b0100:Dval=Hrs;
        default:Dval=4'b0000;
    endcase
    end
        
endmodule

BCD_to_7_segment模組程式碼:

module BCD_to_7_segment(X,Lights);
input [3:0] X;
output reg [6:0] Lights;
reg X3,X2,X1,X0;
reg A,B,C,D,E,F,G;
always @(X)begin
    {X3,X2,X1,X0}=X;
    case({X3,X2,X1,X0})
        4'd0:{A,B,C,D,E,F,G}=7'b1111110;
        4'd1:{A,B,C,D,E,F,G}=7'b0110000;
        4'd2:{A,B,C,D,E,F,G}=7'b1101101;
        4'd3:{A,B,C,D,E,F,G}=7'b1111001;
        4'd4:{A,B,C,D,E,F,G}=7'b0110011;
        4'd5:{A,B,C,D,E,F,G}=7'b1011011;
        4'd6:{A,B,C,D,E,F,G}=7'b1011111;
        4'd7:{A,B,C,D,E,F,G}=7'b1110000;
        4'd8:{A,B,C,D,E,F,G}=7'b1111111;
        4'd9:{A,B,C,D,E,F,G}=7'b1111011;
        default {A,B,C,D,E,F,G}=7'b0000000;
        endcase
        Lights={A,B,C,D,E,F,G};
        end
endmodule

對於Binary-to-BCD還有另外一種思路

本實驗中採用的思路是+3移位取出整數位
這種思路沒有那麼直觀但是高效
另外一種是直接採用C語言的取模除10的思想
這種思路比較簡單直接,但是綜合之後的電路更加複雜,代價很大,但是同樣也能實現目標

程式碼如下

module Tir_Deci(
    input [7:0] SW,
    output [6:0] hrs_Linght,
    output [6:0] hens_Linght,
    output [6:0] ones_Linght
    );
    reg [7:0]Hrs;
    reg [7:0]Tens;
    reg [7:0]Ones;
    wire [7:0] hrs;
    wire [7:0] tens;
    wire [7:0] ones;
    BCD_to_7_segment UUT1(.X(hrs[3:0]),.Lights(hrs_Linght));
    BCD_to_7_segment UUT2(.X(tens[3:0]),.Lights(tens_Linght));
    BCD_to_7_segment UUT3(.X(ones[3:0]),.Lights(ones_Linght));
    binary_to_BCD UU1(.SW(Hrs[3:0]),.BCD(hrs));
    binary_to_BCD UU2(.SW(Tens[3:0]),.BCD(tens));
    binary_to_BCD UU3(.SW(Ones[3:0]),.BCD(ones));
    integer i;
    always@(SW)begin
        i=SW;
        Hrs=i/100;
        Tens=(i/10)%10;
        Ones=(i%10);
    end
endmodule

測試模組程式碼:

程式碼結構
程式碼結構

module Test_bench(

    );
    reg clk;
    reg SW7,SW6,SW5,SW4,SW3,SW2,SW1,SW0;
    wire A,B,C,D,E,F,G;
    wire [3:0]SegSel;
    integer i;
    Top_Module Top(.Clk(clk),.SW7(SW7),.SW6(SW6),.SW5(SW5),.SW4(SW4),.SW3(SW3),.SW2(SW2),.SW1(SW1),
    .SW0(SW0),.A(A),.B(B),.C(C),.D(D),.E(E),.F(F),.G(G),.SegSel_n(SegSel)); 
    initial begin
    clk<=0;
    {SW7,SW6,SW5,SW4,SW3,SW2,SW1,SW0}<=8'b0;
    end
    always begin
    #5 clk<=~clk;
    #100 {SW7,SW6,SW5,SW4,SW3,SW2,SW1,SW0}<={SW7,SW6,SW5,SW4,SW3,SW2,SW1,SW0}+8'b1;
    i={SW7,SW6,SW5,SW4,SW3,SW2,SW1,SW0};
    $write("Iteration %0d",i);
    $write("{%0d,%0d,%0d,%0d}",SegSel[3],SegSel[2],SegSel[1],SegSel[0]);
    $write("{%0d,%0d,%0d,%0d,%0d,%0d,%0d}\n",A,B,C,D,E,F,G);
        if (A) $write(" __\n");else $write("\n");
        if (F) $write("|");else $write(" ");
        if (G) $write("__");else $write("  ");
        if (B) $write("|\n");else $write("\n");
        if (E) $write("|");else $write(" ");
        if (D) $write("__");else $write("  ");
        if (C) $write("|\n");else $write(" \n");
    end
endmodule

實驗效果已經在程式碼前面給出
對於Vivado的使用操作會在其他相關的博文說明

約束檔案

set_property IOSTANDARD LVCMOS33 [get_ports B]
set_property IOSTANDARD LVCMOS33 [get_ports C]
set_property IOSTANDARD LVCMOS33 [get_ports Clk]
set_property IOSTANDARD LVCMOS33 [get_ports D]
set_property IOSTANDARD LVCMOS33 [get_ports E]
set_property IOSTANDARD LVCMOS33 [get_ports A]
set_property IOSTANDARD LVCMOS33 [get_ports F]
set_property IOSTANDARD LVCMOS33 [get_ports G]
set_property IOSTANDARD LVCMOS33 [get_ports SW1]
set_property IOSTANDARD LVCMOS33 [get_ports SW0]
set_property IOSTANDARD LVCMOS33 [get_ports SW3]
set_property IOSTANDARD LVCMOS33 [get_ports SW4]
set_property IOSTANDARD LVCMOS33 [get_ports SW5]
set_property IOSTANDARD LVCMOS33 [get_ports SW6]
set_property IOSTANDARD LVCMOS33 [get_ports SW7]
set_property IOSTANDARD LVCMOS33 [get_ports SW2]
set_property PACKAGE_PIN W16 [get_ports SW2]
set_property PACKAGE_PIN W17 [get_ports SW3]
set_property PACKAGE_PIN W15 [get_ports SW4]
set_property PACKAGE_PIN V15 [get_ports SW5]
set_property PACKAGE_PIN W14 [get_ports SW6]
set_property PACKAGE_PIN W13 [get_ports SW7]
set_property PACKAGE_PIN W7 [get_ports A]
set_property PACKAGE_PIN W6 [get_ports B]
set_property PACKAGE_PIN U8 [get_ports C]
set_property PACKAGE_PIN V8 [get_ports D]
set_property PACKAGE_PIN U5 [get_ports E]
set_property PACKAGE_PIN V5 [get_ports F]
set_property PACKAGE_PIN U7 [get_ports G]
set_property PACKAGE_PIN W5 [get_ports Clk]
set_property PACKAGE_PIN V17 [get_ports SW0]
set_property PACKAGE_PIN V16 [get_ports SW1]



set_property PACKAGE_PIN W4 [get_ports {SegSel_n[3]}]
set_property PACKAGE_PIN V4 [get_ports {SegSel_n[2]}]
set_property PACKAGE_PIN U4 [get_ports {SegSel_n[1]}]
set_property PACKAGE_PIN U2 [get_ports {SegSel_n[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {SegSel_n[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {SegSel_n[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {SegSel_n[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {SegSel_n[0]}]

相關文章