`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Négy számjegyes kijelző modul hexadecimális vagy BCD értékek kijelzésére // Az adatbemenet 16 párhuzamos vonal a 4 számjegy bitjei számára // A kijelzés időmultiplex módon történik, 1kHz körüli kapcsolási frekvenciával // Megjegyzés: Az egység működési módjából következően az adatbemeneti vonalak // értékének változtatása a kijelzési állapothoz képest tetszőleges időpontban // megtörténhet, szinkronizációra nincs szükség. ////////////////////////////////////////////////////////////////////////////////// // LOGSYS IP alapmodulkönyvtár, a LOGSYS FPGA kártyák hardver elemeinek használatához // Készítette: Fehér Béla ////////////////////////////////////////////////////////////////////////////////// module LIP_4digit( input clk16M, // 16MHz frekvenciájú órajel input rst, // Szinkron RESET jel input [15:0] data, // 16 bites adat bemenet (HEX vagy BCD) output [ 7:0] seg, // Szegmens kimenetek output [ 3:0] dig // Digit kimenetek ); /////////////////////////////////////////////////////////////////////////////////// // A léptetés frekvenciája megközelítően 1kHz, amit a 16MHz-es órajelből állítunk elő // A bináris osztó minden 2^14 órajelben előállít egy léptető jelet /////////////////////////////////////////////////////////////////////////////////// reg [13:0] div; // Órajelosztó számláló wire rate = ÷ // Végérték pulzus kiadása, ha minden bit magas always @ (posedge clk16M) // Szekvenciális logika, nem blokkoló értékadásokkal if (rst) div <= 14'b0; // Kezdőállapot beállítása else div <= div + 1; // Számlálás felfelé ////////////////////////////////////////////////////////////////////////////////// // Az időmultiplex vezérlést egy négybites shiftregiszter vezérli, a számjegyek // megjelenítése balról jobbra, MSD -> LSD irányba történik // Ha digit=1000, akkor a digit[3] vonal aktív és a data[15:12] biteken lévő érték jelenik meg az ezrese pozícióban // Ha digit=0100, akkor a digit[2] vonal aktív és a data[11: 8] biteken lévő érték jelenik meg a százas pozícióban // Ha digit=0010, akkor a digit[1] vonal aktív és a data[ 7: 4] biteken lévő érték jelenik meg a tízes pozícióban // Ha digit=0001, akkor a digit[0] vonal aktív és a data[ 3: 0] biteken lévő érték jelenik meg az egyes pozícióban /////////////////////////////////////////////////////////////////////////////////// reg [3:0] digit=4'b1000; always @ (posedge clk16M) // Szekvenciális logika, nem blokkoló értékadásokkal if (rst) digit <= 4'b1000; // Kezdőállapot, digit[3] aktív else if (rate) digit <= {digit[0], digit[3:1]}; // Az adott ütemben a kijelzés vált // A digit jelekkel választhatunk bemeneti 16 bites adat adat számjegyei közül wire [3:0] number; assign number =({4{digit[3]}} & data[15:12]) | // Eloztott multiplexer hálózat, a hatékony erőforrás kihasználáshoz ({4{digit[2]}} & data[11: 8]) | // Egy 4 bites 4-1-be adatkiválasztást valósít meg, AND-OR hálózattal ({4{digit[1]}} & data[ 7: 4]) | ({4{digit[0]}} & data[ 3: 0]); // A kiválasztott számértéket 7 szegmenses kijelző kóddá konvertáljuk // Az átkódoló logikát pozitív logika szerint írjuk fel, azaz az aktív szegmensek értéke 1 // A szegmenskép kódolása a következő: // 0 // --- // 5 | | 1 // --- <--6 // 4 | | 2 // --- . // 3 7 A tizedespont a 7. bit, jelenesetben mindig kikapcsolt reg [7:0] segment; // Változó deklaráció always @(*) // Tisztán kombinációs hálózat, blokkoló értékadásokkal begin case (number) //76543210 szegmensek 4'b0000 : segment = 8'b00111111; // 0 4'b0001 : segment = 8'b00000110; // 1 4'b0010 : segment = 8'b01011011; // 2 4'b0011 : segment = 8'b01001111; // 3 4'b0100 : segment = 8'b01100110; // 4 4'b0101 : segment = 8'b01101101; // 5 4'b0110 : segment = 8'b01111101; // 6 4'b0111 : segment = 8'b00000111; // 7 4'b1000 : segment = 8'b01111111; // 8 4'b1001 : segment = 8'b01101111; // 9 4'b1010 : segment = 8'b01110111; // A 4'b1011 : segment = 8'b01111100; // b 4'b1100 : segment = 8'b00111001; // C 4'b1101 : segment = 8'b01011110; // d 4'b1110 : segment = 8'b01111001; // E 4'b1111 : segment = 8'b01110001; // F default : segment = 8'b00000000; // 0 endcase end assign seg = segment; assign dig = digit; endmodule