2
\$\begingroup\$

I am working with Spartan 2 XC2S50 FPGA Chip on Xilinx board

There is a problem on my design that increases number of used LUTs

and this is the Utility Library :

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;

I think the output of Multiplexer increases the used LUTs, How can I change Multiplexer to decrease used LUTs ?

I have tried many ways, but no chance to decrease enough LUTs.

changing std_logic_vector to bit_vector for port types may be helpful or not ?!

Edit :

I changed design to this :

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;

I declared an array as Memory for LCD characters, but it increased LUTs !, then I changed Process to make LCD character changing sequential but no chance to decrease used LUTs.

How I can declare an array that uses BlockRam instead of LUTs ?

\$\endgroup\$
  • \$\begingroup\$ do you have an eeprom? \$\endgroup\$ – JonRB Jul 30 '17 at 10:17
  • \$\begingroup\$ There is no such part as the XC25S50. Do you mean XC2S50? \$\endgroup\$ – duskwuff Jul 31 '17 at 1:01
  • \$\begingroup\$ @duskwuff , yes ! \$\endgroup\$ – G3ntle_Man Jul 31 '17 at 1:03
  • \$\begingroup\$ You may need to change synthesis options. The synthesiser output ".syr" file explains when it detects memory arrays and how it implements them. \$\endgroup\$ – TEMLIB Jul 31 '17 at 19:53
  • \$\begingroup\$ Also, all FPGA blockRAMs need a clock, you cannot use them as asynchronous giga-multiplexer. you need "data_read<=ram(address);" then, on the next cycle, you may multiplex the data read from the block with other values. \$\endgroup\$ – TEMLIB Jul 31 '17 at 19:57
7
\$\begingroup\$

Put your character data into BlockRAM instead of using LUTs as distributed RAM.

\$\endgroup\$
  • 1
    \$\begingroup\$ Sht, you wrote it first... \$\endgroup\$ – Gregory Kornblum Jul 30 '17 at 10:31
  • \$\begingroup\$ Thanks, the example in the PDF is an array type, but when I declare an Array, it increases used LUTs \$\endgroup\$ – G3ntle_Man Jul 31 '17 at 0:09
4
\$\begingroup\$

Block rams and state machines (So you output one character per clock rather then some sort of honking great parallel bus) are the way to go here (wide muxes are logic hogs).

I could not find the architecture overview for that obsolete part, so could not check what is available but even in that thing there should be some ram available, and there should be a template for instantiating a rom.

\$\endgroup\$
3
\$\begingroup\$

I don't really know how it is synthesised now, but it would be far better if you could output characters sequentially (or assemble the strings over several clock cycles)

You should put all your strings into a pre-initialized RAM block (which can be simply defined as a VHDL array with constants, without using any special Xilinx blocks). Variable text can be tagged with special characters, then selected with a multiplexer.

You may also try to use something as :

ascii_code<=to_unsigned(character'pos(char),8));

for converting from VHDL characters to logic levels.

Making your design more sequential could dramatically reduce its size.

\$\endgroup\$
  • 1
    \$\begingroup\$ thanks, but how I can put theme into a pre-initialized RAM block ?. when I declare an array, it increases the used LUTs. may you give me a working example ? \$\endgroup\$ – G3ntle_Man Jul 31 '17 at 0:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.