Ich arbeite mit dem Spartan 2 XC2S50 FPGA-Chip auf dem Xilinx-Board
Es gibt ein Problem in meinem Design, das die Anzahl der verwendeten LUTs erhöht
und das ist die Utility-Bibliothek:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package Utility is
Type Char_Array is array(natural range <>) of std_logic_vector(7 DownTo 0);
Constant CharArray : Char_Array(0 to 38) := (
"00110000", -- 0
"00110001", -- 1
"00110010", -- 2
"00110011", -- 3
"00110100", -- 4
"00110101", -- 5
"00110110", -- 6
"00110111", -- 7
"00111000", -- 8
"00111001", -- 9
"01000001", -- 10 : A
"01000010", -- 11 : B
"01000011", -- 12 : C
"01000100", -- 13 : D
"01000101", -- 14 : E
"01000110", -- 15 : F
"01000111", -- 16 : G
"01001000", -- 17 : H
"01001001", -- 18 : I
"01001010", -- 19 : J
"01001011", -- 20 : K
"01001100", -- 21 : L
"01001101", -- 22 : M
"01001110", -- 23 : N
"01001111", -- 24 : O
"01010000", -- 25 : P
"01010001", -- 26 : Q
"01010010", -- 27 : R
"01010011", -- 28 : S
"01010100", -- 29 : T
"01010101", -- 30 : U
"01010110", -- 31 : V
"01010111", -- 32 : W
"01011000", -- 33 : X
"01011001", -- 34 : Y
"01011010", -- 35 : Z
"00111010", -- 36 : ":"
"00100000", -- 37 : Space
"10110000"); -- 38 : -
-- Type LCD_Text is Array(natural range <>) of std_logic_vector(7 Downto 0);
-- SubType LCD_Line is LCD_Text(1 to 16);
function reverse_vector(a : IN std_logic_vector) return std_logic_vector;
function StdCharNum(I : std_logic) return std_logic_vector;
end Utility;
package body Utility is
function reverse_vector(a : IN std_logic_vector) return std_logic_vector is
variable result: std_logic_vector(a'RANGE);
alias aa: std_logic_vector(a'REVERSE_RANGE) is a;
begin
for i in aa'RANGE loop
result(i) := aa(i);
end loop;
return result;
end;
function StdCharNum(I : std_logic) return std_logic_vector is
begin
Case I IS
when '0' =>
return CharArray(0);
when '1' =>
return CharArray(1);
when others =>
return CharArray(37);
end case;
end;
end Utility;
Ich denke, die Ausgabe des Multiplexers erhöht die verwendeten LUTs. Wie kann ich den Multiplexer ändern, um die verwendeten LUTs zu verringern?
Ich habe viele Möglichkeiten ausprobiert, aber keine Chance, genügend LUTs zu verringern.
Das Ändern von std_logic_vector in bit_vector für Porttypen kann hilfreich sein oder nicht?!
Bearbeiten :
Ich habe das Design so geändert:
library ieee ;
...
Entity Main IS
PORT(CLOCK : IN STD_LOGIC;
Kb_RK : IN STD_LOGIC_VECTOR(3 DOWNTO 1);
LCDSelector : IN STD_LOGIC_VECTOR(3 Downto 0);
MemAddr : IN STD_LOGIC_VECTOR(11 Downto 0);
DE : OUT STD_LOGIC_VECTOR(3 DOWNTO 1);
Seg_Out : OUT STD_LOGIC_VECTOR(7 Downto 0);
LED_Row : OUT STD_LOGIC_VECTOR(7 Downto 0);
LED_Col : OUT STD_LOGIC_VECTOR(7 Downto 0);
Buz_Out : OUT STD_LOGIC;
LCD_RW, LCD_RS, LCD_EN : OUT STD_LOGIC;
LCD_Data : OUT STD_LOGIC_VECTOR(7 Downto 0));
END Main;
Architecture Structure OF Main IS
Component Base_Com is
Port(CLK : IN std_logic;
Reset_In : IN std_logic;
INPR_In : IN std_logic_vector(7 Downto 0);
Instruction : IN std_logic_vector(15 Downto 0);
RunMode : IN std_logic; -- 0 = Normal 1 = Debug;
RunDelay : IN std_logic_vector(2 Downto 0);
MemDispAddr : IN std_logic_vector(11 Downto 0);
Start, Step : IN std_logic := '0';
State : OUT std_logic_vector(2 Downto 0);
AC_Out, DR_Out, IR_Out, TR_Out : OUT std_logic_vector(15 Downto 0);
AR_Out, PC_Out : OUT std_logic_vector(11 Downto 0);
INPR_Out, OUTR_Out : OUT std_logic_vector(7 Downto 0);
Mem_Out : OUT std_logic_vector(15 Downto 0);
Flag_I, Flag_S, Flag_E, Flag_R,
Flag_IEN, Flag_FGI, Flag_FGO : OUT std_logic);
End Component;
Component Keyboard IS
PORT(Clock : IN STD_LOGIC;
Reset : IN STD_LOGIC;
BCState : IN STD_LOGIC_VECTOR(2 Downto 0);
RK : IN STD_LOGIC_VECTOR(3 DOWNTO 1);
DE : OUT STD_LOGIC_VECTOR(3 DOWNTO 1);
Invalid_Key : OUT STD_LOGIC;
IC : OUT STD_LOGIC_VECTOR(7 Downto 0);
PC : OUT STD_LOGIC_VECTOR(7 Downto 0);
ProgState : OUT STD_LOGIC_VECTOR(1 Downto 0);
Key : OUT STD_LOGIC_VECTOR(16 Downto 1);
Ins : OUT STD_LOGIC_VECTOR(15 Downto 0);
BCRunMode : OUT STD_LOGIC;
BCRunDelay : OUT STD_LOGIC_VECTOR(2 Downto 0);
BCStart, BCStep, BCReset : OUT STD_LOGIC);
End Component;
Component Buzzer Is
...
End Component;
Component LEDMatrix is
...
end Component;
Component LCD_Controller is
Port(Clk : IN STD_LOGIC; --system clock
Reset_n : IN STD_LOGIC; --active low reinitializes lcd
LCD_Enable : IN STD_LOGIC; --latches data into lcd controller
LCD_Bus : IN STD_LOGIC_VECTOR(9 DOWNTO 0); --data and control signals
Busy : OUT STD_LOGIC := '1'; --lcd controller busy/idle feedback
RW, RS, E : OUT STD_LOGIC; --read/write, setup/data, and enable for lcd
LCD_Data : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --data signals for lcd
end Component;
Signal Key : STD_LOGIC_VECTOR(16 Downto 1);
Signal KBState : STD_LOGIC_VECTOR(1 Downto 0);
Signal InvalidKey : STD_LOGIC := '0';
Signal LEDRow1, LEDRow2 : STD_LOGIC_VECTOR(7 Downto 0) := "00000000";
Signal LEDRow : STD_LOGIC_VECTOR(7 Downto 0) := "00000001";
Signal BuzOut : STD_LOGIC := '0';
Signal ICBinary : STD_LOGIC_VECTOR(7 Downto 0) := "00000000";
Signal PCBinary : STD_LOGIC_VECTOR(7 Downto 0) := "00000000";
Signal ICTens, ICOnes, PCTens, PCOnes : STD_LOGIC_VECTOR(3 Downto 0) := "0010";
Signal ICSeg1, ICSeg2, PCSeg1, PCSeg2 : STD_LOGIC_VECTOR(7 Downto 0) := "00000000";
Signal Kb_DE : STD_LOGIC_VECTOR(3 Downto 1) := "000";
Signal LCD_Enable : STD_LOGIC;
Signal LCD_Busy : STD_LOGIC;
Signal LCD_Bus : STD_LOGIC_VECTOR(9 Downto 0);
Signal CurrentLCDLine : STD_LOGIC := '0';
------
Signal BCReset, BCRunMode, BCStart, BCStep : std_logic := '0';
Signal BCRunDelay : std_logic_vector(2 Downto 0);
Signal BCState : std_logic_vector(2 Downto 0);
Signal INPR_In : std_logic_vector(7 Downto 0);
Signal Ins : std_logic_vector(15 Downto 0);
Signal AC, DR, IR, TR, Mem : std_logic_vector(15 Downto 0);
Signal AR, PC : std_logic_vector(11 Downto 0);
Signal INPR, OUTR : std_logic_vector(7 Downto 0);
Signal I, S, E, R, IEN, FGI, FGO : std_logic;
------
Signal LCDCounter : Integer range 0 to 32 := 0;
Signal LCDWrite : std_logic := '0';
-- Type LCD_Memory is Array(1 to 208) of std_logic_vector(7 Downto 0);
-- Constant LCDMemory : LCD_Memory :=
--
-- ("01010000", "01010010", "01001111", "01000111", "01010010", "01000001", "01001101", "00100000", -- Line_PK - 1
-- "10110000", "00100000", "01001011", "01000101", "01011001", "00100000", "00111010", "00100000",
--
-- "01000101", "01001110", "01010100", "01000101", "01010010", "00100000", "01010010", "01010101", -- Line_GM - 17
-- "01001110", "00100000", "01001101", "01001111", "01000100", "01000101", "00100000", "00111010",
--
-- "01000101", "01001110", "01010100", "01000101", "01010010", "00100000", "01010010", "01010101", -- Line_GD - 33
-- "01001110", "00100000", "01000100", "01000101", "01001100", "01000001", "01011001", "00111010",
--
-- "01010010", "01010101", "01001110", "10110000", "01000100", "00100000", "00100000", "00100000", -- Line_RD - 49
--
-- "01010010", "01010101", "01001110", "10110000", "01001110", "00100000", "00100000", "00100000", -- Line_RN - 57
--
-- "01000100", "01001111", "01001110", "01000101", "00100000", "00100000", "00100000", "00100000", -- Line_DN - 65
--
-- "01001101", "01000101", "01001101", "01001111", "01010010", "01011001", "00100000", "00111010", -- Line_Mem - 73
-- "01000001", "01000011", "00100000", "00111010", "00100000", "00100000", "00100000", "00100000", -- Line_AC - 81
-- "01000100", "01010010", "00100000", "00111010", "00100000", "00100000", "00100000", "00100000", -- Line_DR - 89
-- "01001001", "01010010", "00100000", "00111010", "00100000", "00100000", "00100000", "00100000", -- Line_IR - 97
-- "01010100", "01010010", "00100000", "00111010", "00100000", "00100000", "00100000", "00100000", -- Line_TR - 105
-- "01000001", "01010010", "00100000", "00111010", "00100000", "00100000", "00100000", "00100000", -- Line_AR - 113
-- "01001001", "01001110", "01010000", "01010010", "00100000", "00111010", "00100000", "00100000", -- Line_INPR - 121
-- "01001111", "01010101", "01010100", "01010010", "00100000", "00111010", "00100000", "00100000", -- Line_OUTR - 129
--
-- "01001001", "00100000", "00111010", "00100000", "00100000", "00100000", "00100000", "00100000", -- Line_I - 137
-- "01010011", "00100000", "00111010", "00100000", "00100000", "00100000", "00100000", "00100000", -- Line_S - 145
-- "01000101", "00100000", "00111010", "00100000", "00100000", "00100000", "00100000", "00100000", -- Line_E - 153
-- "01010010", "00100000", "00111010", "00100000", "00100000", "00100000", "00100000", "00100000", -- Line_R - 161
-- "01001001", "01000101", "01001110", "00100000", "00111010", "00100000", "00100000", "00100000", -- Line_IEN - 169
-- "01000110", "01000111", "01001001", "00100000", "00111010", "00100000", "00100000", "00100000", -- Line_FGI - 177
-- "01000110", "01000111", "01001111", "00100000", "00111010", "00100000", "00100000", "00100000", -- Line_FGO - 185
-- "00100000", "00100000", "00100000", "00100000", "00100000", "00100000", "00100000", "00100000", -- Null_1 - 193
-- "00100000", "00100000", "00100000", "00100000", "00100000", "00100000", "00100000", "00100000"); -- Null_2 - 201
Begin
BC : Base_Com Port Map(Clock, BCReset, INPR_In, Ins, BCRunMode, BCRunDelay, MemAddr, BCStart, BCStep, BCState,
AC, DR, IR, TR, AR, PC, INPR, OUTR, Mem, I, S, E, R, IEN, FGI, FGO);
LEDRow1 <= Key(16 Downto 9);
LEDRow2 <= Key(8 Downto 1);
KB : Keyboard Port Map(Clock, '0', BCState, Kb_RK, Kb_DE, InvalidKey, ICBinary, PCBinary,
KBState, Key, Ins, BCRunMode, BCRunDelay, BCStart, BCStep, BCReset);
ICTens <= ICBinary(7 Downto 4);
ICOnes <= ICBinary(3 Downto 0);
PCTens <= PCBinary(7 Downto 4);
PCOnes <= PCBinary(3 Downto 0);
LM : LEDMatrix Port Map(Clock, LEDRow1, LEDRow2, LED_Row, LED_Col);
BZ : Buzzer Generic Map(15465)
Port Map(Clock, BuzOut);
LCD : LCD_Controller Port Map(Clock, '1', LCD_Enable, LCD_Bus, LCD_Busy, LCD_RW, LCD_RS, LCD_EN, LCD_Data);
-- MLCD : MUX_LCD Port Map(Clock, LCDSelector, BCState, KBState, BCRunMode, BCRunDelay, Key, Mem, AC, DR, IR, TR,
-- AR, INPR, OUTR, I, S, E, R, IEN, FGI, FGO, LCDText1);
with ICTens Select
ICSeg1 <= "00000110" when "0001", "00111111" when others;
with ICOnes Select
ICSeg2 <= "00000110" when "0001", "01011011" when "0010", "01001111" when "0011", "01100110" when "0100",
"01101101" when "0101", "01111101" when "0110", "00100111" when "0111", "01111111" when "1000",
"01101111" when "1001", "00111111" when others;
with PCTens Select
PCSeg1 <= "00000110" when "0001", "01011011" when "0010", "01001111" when "0011", "01100110" when "0100",
"01101101" when "0101", "01111101" when "0110", "00100111" when "0111", "01111111" when "1000",
"01101111" when "1001", "00111111" when others;
with PCOnes Select
PCSeg2 <= "00000110" when "0001", "01011011" when "0010", "01001111" when "0011", "01100110" when "0100",
"01101101" when "0101", "01111101" when "0110", "00100111" when "0111", "01111111" when "1000",
"01101111" when "1001", "00111111" when others;
DE <= Kb_DE;
with Kb_DE Select
Seg_Out <= ICSeg1 when "000", ICSeg2 when "001", PCSeg1 when "100", PCSeg2 when "101", (others => '0') when others;
Process(InvalidKey, BuzOut)
begin
if (InvalidKey = '1') then
Buz_Out <= BuzOut;
else
Buz_Out <= '0';
end if;
end Process;
-- Process(BCState, BCRunMode, BCRunDelay, KBState, Key, MemAddr, Mem, AC, DR, IR, TR, AR, INPR, OUTR, I, S, E, R, IEN, FGI, FGO)
-- begin
-- LCDWrite <= '1';
-- end Process;
Process(Clock)
begin
if (Clock'Event and Clock = '1') then
-- if LCDWrite = '1' then
if (LCD_Busy = '0' and LCD_Enable = '0') then
LCD_Enable <= '1';
LCDCounter <= LCDCounter + 1;
if (LCDCounter = 17) and (CurrentLCDLine = '0') then
LCD_Bus <= "0011000000";
LCDCounter <= 16;
CurrentLCDLine <= '1';
else
case KBState is
when "00" => -- Program
case LCDCounter is
when 1 =>
LCD_Bus <= "10" & CharArray(25);
when 2 =>
LCD_Bus <= "10" & CharArray(27);
when 3 =>
LCD_Bus <= "10" & CharArray(24);
when 4 =>
LCD_Bus <= "10" & CharArray(16);
when 5 =>
LCD_Bus <= "10" & CharArray(27);
when 6 =>
LCD_Bus <= "10" & CharArray(10);
when 7 =>
LCD_Bus <= "10" & CharArray(22);
when 8 =>
LCD_Bus <= "10" & CharArray(37);
when 9 =>
LCD_Bus <= "10" & CharArray(38);
when 10 =>
LCD_Bus <= "10" & CharArray(37);
when 11 =>
LCD_Bus <= "10" & CharArray(20);
when 12 =>
LCD_Bus <= "10" & CharArray(14);
when 13 =>
LCD_Bus <= "10" & CharArray(34);
when 14 =>
LCD_Bus <= "10" & CharArray(37);
when 15 =>
LCD_Bus <= "10" & CharArray(36);
when 16 =>
LCD_Bus <= "10" & CharArray(37);
when others =>
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & Key(LCDCounter - 16))));
end case; -- counter case
when "01" => -- GetMode
case LCDCounter is
when 1 =>
LCD_Bus <= "10" & CharArray(14);
when 2 =>
LCD_Bus <= "10" & CharArray(13);
when 3 =>
LCD_Bus <= "10" & CharArray(29);
when 4 =>
LCD_Bus <= "10" & CharArray(14);
when 5 =>
LCD_Bus <= "10" & CharArray(27);
when 6 =>
LCD_Bus <= "10" & CharArray(37);
when 7 =>
LCD_Bus <= "10" & CharArray(27);
when 8 =>
LCD_Bus <= "10" & CharArray(30);
when 9 =>
LCD_Bus <= "10" & CharArray(23);
when 10 =>
LCD_Bus <= "10" & CharArray(37);
when 11 =>
LCD_Bus <= "10" & CharArray(22);
when 12 =>
LCD_Bus <= "10" & CharArray(24);
when 13 =>
LCD_Bus <= "10" & CharArray(13);
when 14 =>
LCD_Bus <= "10" & CharArray(14);
when 15 =>
LCD_Bus <= "10" & CharArray(37);
when 16 =>
LCD_Bus <= "10" & CharArray(36);
when others =>
if LCDCounter = 17 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & BCRunMode)));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case; -- counter case
when "10" => -- GetDelay
case LCDCounter is
when 1 =>
LCD_Bus <= "10" & CharArray(14);
when 2 =>
LCD_Bus <= "10" & CharArray(13);
when 3 =>
LCD_Bus <= "10" & CharArray(29);
when 4 =>
LCD_Bus <= "10" & CharArray(14);
when 5 =>
LCD_Bus <= "10" & CharArray(27);
when 6 =>
LCD_Bus <= "10" & CharArray(37);
when 7 =>
LCD_Bus <= "10" & CharArray(27);
when 8 =>
LCD_Bus <= "10" & CharArray(30);
when 9 =>
LCD_Bus <= "10" & CharArray(23);
when 10 =>
LCD_Bus <= "10" & CharArray(37);
when 11 =>
LCD_Bus <= "10" & CharArray(22);
when 12 =>
LCD_Bus <= "10" & CharArray(24);
when 13 =>
LCD_Bus <= "10" & CharArray(13);
when 14 =>
LCD_Bus <= "10" & CharArray(14);
when 15 =>
LCD_Bus <= "10" & CharArray(37);
when 16 =>
LCD_Bus <= "10" & CharArray(36);
when others =>
if LCDCounter = 17 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned(BCRunDelay)));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case; -- counter case
when others =>
case LCDCounter is
when 1 =>
if BCState = "110" then
LCD_Bus <= "10" & CharArray(13);
else
LCD_Bus <= "10" & CharArray(27);
end if;
when 2 =>
if BCState = "110" then
LCD_Bus <= "10" & CharArray(24);
else
LCD_Bus <= "10" & CharArray(30);
end if;
when 3 =>
LCD_Bus <= "10" & CharArray(23);
when 4 =>
if BCState = "110" then
LCD_Bus <= "10" & CharArray(14);
else
LCD_Bus <= "10" & CharArray(38);
end if;
when 5 =>
if BCState = "110" then
LCD_Bus <= "10" & CharArray(37);
else
if BCRunMode = '1' then
LCD_Bus <= "10" & CharArray(13);
else
LCD_Bus <= "10" & CharArray(23);
end if;
end if;
when 6|7|8 =>
LCD_Bus <= "10" & CharArray(37);
when others =>
case LCDSelector is
when "0000" => -- Memory
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(22);
when 10 =>
LCD_Bus <= "10" & CharArray(14);
when 11 =>
LCD_Bus <= "10" & CharArray(22);
when 12 =>
LCD_Bus <= "10" & CharArray(24);
when 13 =>
LCD_Bus <= "10" & CharArray(27);
when 14 =>
LCD_Bus <= "10" & CharArray(34);
when 15 =>
LCD_Bus <= "10" & CharArray(37);
when 16 =>
LCD_Bus <= "10" & CharArray(36);
when others =>
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & Mem(32 - LCDCounter))));
end case;
when "0001" => -- AC
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(10);
when 10 =>
LCD_Bus <= "10" & CharArray(12);
when 11 =>
LCD_Bus <= "10" & CharArray(37);
when 12 =>
LCD_Bus <= "10" & CharArray(36);
when 13|14|15|16 =>
LCD_Bus <= "10" & CharArray(37);
when others =>
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & AC(32 - LCDCounter))));
end case;
when "0010" => -- DR
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(13);
when 10 =>
LCD_Bus <= "10" & CharArray(27);
when 11 =>
LCD_Bus <= "10" & CharArray(37);
when 12 =>
LCD_Bus <= "10" & CharArray(36);
when 13|14|15|16 =>
LCD_Bus <= "10" & CharArray(37);
when others =>
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & DR(32 - LCDCounter))));
end case;
when "0011" => -- IR
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(18);
when 10 =>
LCD_Bus <= "10" & CharArray(27);
when 11 =>
LCD_Bus <= "10" & CharArray(37);
when 12 =>
LCD_Bus <= "10" & CharArray(36);
when 13|14|15|16 =>
LCD_Bus <= "10" & CharArray(37);
when others =>
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & IR(32 - LCDCounter))));
end case;
when "0100" => -- TR
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(29);
when 10 =>
LCD_Bus <= "10" & CharArray(27);
when 11 =>
LCD_Bus <= "10" & CharArray(37);
when 12 =>
LCD_Bus <= "10" & CharArray(36);
when 13|14|15|16 =>
LCD_Bus <= "10" & CharArray(37);
when others =>
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & TR(32 - LCDCounter))));
end case;
when "0101" => -- AR
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(10);
when 10 =>
LCD_Bus <= "10" & CharArray(27);
when 11 =>
LCD_Bus <= "10" & CharArray(37);
when 12 =>
LCD_Bus <= "10" & CharArray(36);
when 13|14|15|16 =>
LCD_Bus <= "10" & CharArray(37);
when others =>
if LCDCounter < 29 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & AR(32 - LCDCounter - 4))));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case;
when "0110" => -- INPR
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(18);
when 10 =>
LCD_Bus <= "10" & CharArray(23);
when 11 =>
LCD_Bus <= "10" & CharArray(25);
when 12 =>
LCD_Bus <= "10" & CharArray(27);
when 13 =>
LCD_Bus <= "10" & CharArray(37);
when 14 =>
LCD_Bus <= "10" & CharArray(36);
when 15|16 =>
LCD_Bus <= "10" & CharArray(37);
when others =>
if LCDCounter < 25 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & INPR(32 - LCDCounter - 8))));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case;
when "0111" => -- OUTR
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(24);
when 10 =>
LCD_Bus <= "10" & CharArray(30);
when 11 =>
LCD_Bus <= "10" & CharArray(29);
when 12 =>
LCD_Bus <= "10" & CharArray(27);
when 13 =>
LCD_Bus <= "10" & CharArray(37);
when 14 =>
LCD_Bus <= "10" & CharArray(36);
when 15|16 =>
LCD_Bus <= "10" & CharArray(37);
when others =>
if LCDCounter < 25 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & OUTR(32 - LCDCounter - 8))));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case;
when "1000" => -- I
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(18);
when 10 =>
LCD_Bus <= "10" & CharArray(37);
when 11 =>
LCD_Bus <= "10" & CharArray(36);
when others =>
if LCDCounter = 17 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & I)));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case;
when "1001" => -- S
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(28);
when 10 =>
LCD_Bus <= "10" & CharArray(37);
when 11 =>
LCD_Bus <= "10" & CharArray(36);
when others =>
if LCDCounter = 17 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & S)));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case;
when "1010" => -- E
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(14);
when 10 =>
LCD_Bus <= "10" & CharArray(37);
when 11 =>
LCD_Bus <= "10" & CharArray(36);
when others =>
if LCDCounter = 17 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & E)));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case;
when "1011" => -- R
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(27);
when 10 =>
LCD_Bus <= "10" & CharArray(37);
when 11 =>
LCD_Bus <= "10" & CharArray(36);
when others =>
if LCDCounter = 17 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & R)));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case;
when "1100" => -- IEN
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(18);
when 10 =>
LCD_Bus <= "10" & CharArray(14);
when 11 =>
LCD_Bus <= "10" & CharArray(23);
when 12 =>
LCD_Bus <= "10" & CharArray(37);
when 13 =>
LCD_Bus <= "10" & CharArray(36);
when others =>
if LCDCounter = 17 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & IEN)));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case;
when "1101" => -- FGI
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(15);
when 10 =>
LCD_Bus <= "10" & CharArray(16);
when 11 =>
LCD_Bus <= "10" & CharArray(18);
when 12 =>
LCD_Bus <= "10" & CharArray(37);
when 13 =>
LCD_Bus <= "10" & CharArray(36);
when others =>
if LCDCounter = 17 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & FGI)));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case;
when "1110" => -- FGO
case LCDCounter is
when 9 =>
LCD_Bus <= "10" & CharArray(15);
when 10 =>
LCD_Bus <= "10" & CharArray(16);
when 11 =>
LCD_Bus <= "10" & CharArray(24);
when 12 =>
LCD_Bus <= "10" & CharArray(37);
when 13 =>
LCD_Bus <= "10" & CharArray(36);
when others =>
if LCDCounter = 17 then
LCD_Bus <= "10" & CharArray(to_integer(unsigned'("" & FGO)));
else
LCD_Bus <= "10" & CharArray(37);
end if;
end case;
when others =>
null;
end case;
end case;
end case;
if LCDCounter = 32 then
LCDCounter <= 0;
CurrentLCDLine <= '0';
end if;
else
LCD_Enable <= '0';
end if;
-- else
-- LCD_Enable <= '0';
-- end if;
end if;
end Process;
End Structure;
Ich habe ein Array als Speicher für LCD-Zeichen deklariert, aber es hat die LUTs erhöht! Dann habe ich den Prozess geändert, um den LCD-Zeichenwechsel sequenziell zu machen, aber keine Chance, die verwendeten LUTs zu verringern.
Wie kann ich ein Array deklarieren, das BlockRam anstelle von LUTs verwendet?
Legen Sie Ihre Charakterdaten in BlockRAM ab, anstatt LUTs als verteiltes RAM zu verwenden.
Block-RAMs und Zustandsmaschinen (Sie geben also ein Zeichen pro Takt aus, anstatt eine Art hupenden großen parallelen Bus) sind hier der richtige Weg (breite Muxes sind logische Schweine).
Ich konnte die Architekturübersicht für diesen veralteten Teil nicht finden, konnte also nicht überprüfen, was verfügbar ist, aber selbst in diesem Ding sollte etwas RAM verfügbar sein, und es sollte eine Vorlage zum Instanziieren eines Roms geben.
Ich weiß nicht wirklich, wie es jetzt synthetisiert wird, aber es wäre weitaus besser, wenn Sie Zeichen nacheinander ausgeben könnten (oder die Zeichenfolgen über mehrere Taktzyklen zusammenstellen könnten).
Sie sollten alle Ihre Strings in einen vorinitialisierten RAM-Block legen (der einfach als VHDL-Array mit Konstanten definiert werden kann, ohne spezielle Xilinx-Blöcke zu verwenden). Variabler Text kann mit Sonderzeichen gekennzeichnet und dann mit einem Multiplexer ausgewählt werden.
Sie können auch versuchen, etwas zu verwenden als:
ascii_code<=to_unsigned(character'pos(char),8));
zum Konvertieren von VHDL-Zeichen in logische Ebenen.
Wenn Sie Ihr Design sequenzieller gestalten, könnte es seine Größe drastisch reduzieren.
Benutzer16222
Benutzer39382
Mahmud_Mehri
TEMLIB
TEMLIB