makehex.vhd

来自「Actel Fusion System Management Developme」· VHDL 代码 · 共 521 行 · 第 1/2 页

VHD
521
字号
-- ********************************************************************/ 
-- Copyright 2007 Actel Corporation.  All rights reserved.
-- IP Engineering 
--
-- ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN 
-- ACCORDANCE WITH THE ACTEL LICENSE AGREEMENT AND MUST BE APPROVED 
-- IN ADVANCE IN WRITING.  
--  
-- File:  makehex.vhd
--     
-- Description: Simple APB Bus Controller
--              Creates Hex Image Files  
--
-- Rev: 2.3   01Mar07 IPB  : Production Release   
--
-- Notes:
--   Converts the instructions encoded in instruction.txt into HEX files
--   
--
-- *********************************************************************/ 

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

use work.misc.all;
use work.textio.all;
use work.support.all;

use std.textio.all;


entity MAKEHEX is
  generic ( ENABLE   : boolean;
            ID       : integer range 0 to 9 ;
            FAMILY   : integer range 0 to 99;
            AWIDTH   : integer range 1 to 16;  
            DWIDTH   : integer range 8 to 32;   
            SDEPTH   : integer range 1 to 16;    
            ICWIDTH  : integer range 1 to 16;  
            IIWIDTH  : integer range 1 to 31;  
            IFWIDTH  : integer range 0 to 28;
            TESTMODE : integer range 0 to 99
           );
end MAKEHEX;


architecture RTL of MAKEHEX is

constant IWWIDTH    : integer := 32+16+4+6;   -- =58
constant SWIDTH     : integer := calc_swidth(SDEPTH);

constant AW : integer := AWIDTH;
constant DW : integer := DWIDTH;
constant SW : integer := max(1,SWIDTH);
constant IW : integer := ICWIDTH;

constant RAMDEPTH : integer := 2**IW;
constant RAMWIDTH : integer := AW+DW+SW+6;

constant NROWS   : integer := 1+ (RAMDEPTH-1)/512 ;
constant NCOLS   : integer := 1+ (RAMWIDTH-1)/9 ;
constant NRAMS   : integer :=  NCOLS*NROWS ;
constant RIDEPTH : integer :=  NRAMS*512 ;
constant RIWIDTH : integer :=  log2r(RIDEPTH);

constant APA  : boolean := (FAMILY=14);

component INSTRUCTIONS 
  generic ( AWIDTH   : integer range 1 to 16;  
            DWIDTH   : integer range 8 to 32;   
            SWIDTH   : integer range 0 to 4 ;    
            ICWIDTH  : integer range 1 to 16;  
            IIWIDTH  : integer range 1 to 32;
            IFWIDTH  : integer range 0 to 28;     
            IWWIDTH  : integer range 1 to 64;
            EN_MULT  : integer range 0 to 3;
            EN_INC   : integer range 0 to 1;
            ID       : integer range 0 to 9;
            TESTMODE : integer range 0 to 99
           );
  port     ( ADDRESS     : in  std_logic_vector(ICWIDTH-1 downto 0);
             INSTRUCTION : out std_logic_vector(IWWIDTH-1 downto 0)        
           );
end component;

signal  ADDRESS       : std_logic_vector(ICWIDTH-1 downto 0);
signal  INSTRUCTION   : std_logic_vector(IWWIDTH-1 downto 0);
signal  INSTRUCTIONX  : std_logic_vector(IWWIDTH-1 downto 0);
signal  INSCOMPRESSED : std_logic_vector(IWWIDTH-1+9 downto 0); -- RAM may be wider than instructions
    
constant DEBUG : BOOLEAN := FALSE;


subtype BYTEX       is std_logic_vector (7 downto 0);
type BYTE_ARRAYX    is array ( INTEGER range <>) of BYTEX;

function to_char( x: std_logic_vector) return character is
variable x1 :integer range 0 to 15;
variable c  : character;
begin
  x1 := conv_integer(x);
  case x1 is
    when 0  => c := '0';
    when 1  => c := '1';
    when 2  => c := '2';
    when 3  => c := '3';
    when 4  => c := '4';
    when 5  => c := '5';
    when 6  => c := '6';
    when 7  => c := '7';
    when 8  => c := '8';
    when 9  => c := '9';
    when 10 => c := 'A';
    when 11 => c := 'B';
    when 12 => c := 'C';
    when 13 => c := 'D';
    when 14 => c := 'E';
    when 15 => c := 'F';
  end case;
  return(c);
end to_char;
       
    
function create_ihex(n,addr : integer;  bytes : byte_arrayx ) return string is
variable p : integer;
variable str : string(1 to 80);
variable x   : std_logic_vector(31 downto 0);
variable csum : std_logic_vector(7 downto 0);
begin
 p := 1;
 csum := ( others => '0');
 str := ( others => NUL );
 str(1) := ':';
 x := conv_std_logic_vector(n,32);  
 str(2) :=to_char(x(7 downto 4));
 str(3) :=to_char(x(3 downto 0));
 csum := csum + x(7 downto 0);
 x := conv_std_logic_vector(addr,32);
 for i in 0 to 3 loop
   str(4+i) := to_char(x(15-4*i downto 12-4*i));
 end loop;
 csum := csum + x(15 downto 8) + x(7 downto 0);
 x := conv_std_logic_vector(0,32);  -- record type
 str(8) :=to_char(x(7 downto 4));
 str(9) :=to_char(x(3 downto 0));
 csum := csum + x(7 downto 0); 
 for i in 0 to n-1 loop
   str(10+2*i) :=to_char(bytes(i)(7 downto 4));
   str(11+2*i) :=to_char(bytes(i)(3 downto 0));
   csum := csum + bytes(i);
 end loop;
 csum := 1 -csum -1;
 str(10+2*n) := to_char(csum(7 downto 4));
 str(11+2*n) := to_char(csum(3 downto 0));
 return(str(1 to 80));
end create_ihex;    
    
--:020000021000EC
    
function create_addr_ihex(addr : integer ) return string is
variable p : integer;
variable str : string(1 to 80);
variable x   : std_logic_vector(31 downto 0);
variable csum : std_logic_vector(7 downto 0);
begin
 p := 1;
 csum := ( others => '0');
 str := ( others => NUL );
 str(1) := ':';
 x := conv_std_logic_vector(2,32);  
 str(2) :=to_char(x(7 downto 4));
 str(3) :=to_char(x(3 downto 0));
 csum := csum + x(7 downto 0);
 x := conv_std_logic_vector(0,32);
 for i in 0 to 3 loop
   str(4+i) := to_char(x(15-4*i downto 12-4*i));
 end loop;
 csum := csum + x(15 downto 8) + x(7 downto 0);
 x := conv_std_logic_vector(02,32); -- record type
 str(8) :=to_char(x(7 downto 4));
 str(9) :=to_char(x(3 downto 0));
 csum := csum + x(7 downto 0); 
 x := conv_std_logic_vector(addr,32);   -- record type 2
 x(15 downto 0) := x(19 downto 4);      -- shift by 4
 str(10) :=to_char(x(15 downto 12));
 str(11) :=to_char(x(11 downto 8));
 str(12) :=to_char(x(7 downto 4));
 str(13) :=to_char(x(3 downto 0));
 csum := csum + x(15 downto 8);
 csum := csum + x(7 downto 0);
 csum := 1 -csum -1;
 str(10+2*2) := to_char(csum(7 downto 4));
 str(11+2*2) := to_char(csum(3 downto 0));
 return(str(1 to 80));
end create_addr_ihex;   
        
begin
    
-------------------------------------------------------------------------------------------------
-- VHDL Code with Instruction Sequence
-- Note this gives out a 58 bit instruction heavily populated with dont cares


UINS : INSTRUCTIONS  generic map
          ( AWIDTH   => AWIDTH,  
            DWIDTH   => DWIDTH,   
            SWIDTH   => SWIDTH,    
            EN_MULT  => 1,           -- assume MULT and no INC
            EN_INC   => 0,           -- INC's will be mapped to ADDS
            ICWIDTH  => ICWIDTH, 
            IIWIDTH  => IIWIDTH, 
            IFWIDTH  => IFWIDTH, 
            IWWIDTH  => IWWIDTH, 
            ID       => ID,
            TESTMODE => TESTMODE
           )
  port map ( ADDRESS     => ADDRESS,    
             INSTRUCTION => INSTRUCTIONX      
           );

-------------------------------------------------------------------------------------------------
-- Remove Dont Cares

process(INSTRUCTIONX)
begin
  for j in INSTRUCTIONX'range loop
    if INSTRUCTIONX(j)='0' or INSTRUCTIONX(j)='1' then
      INSTRUCTION(j) <= INSTRUCTIONX(j);
    else
      INSTRUCTION(j) <= '0';
    end if;
  end loop;
end process;    

-- Compress the 58 Bit instruction to the Miniumn Size based on AW,DW,SW
process(INSTRUCTION)
begin   
  INSCOMPRESSED <= ( others => '0');
  INSCOMPRESSED(5 downto 0) <= INSTRUCTION(5 downto 0);
  if SW>0 then
    INSCOMPRESSED(SW-1+6 downto 6) <= INSTRUCTION(SW-1+6 downto 6); 
  end if;   
  INSCOMPRESSED(AW-1+SW+6 downto SW+6)        <= INSTRUCTION(AW-1+4+6 downto 4+6);        
  INSCOMPRESSED(DW-1+AW+SW+6 downto AW+SW+6 ) <= INSTRUCTION(DW-1+16+4+6 downto 16+4+6 ); 
end process;


-------------------------------------------------------------------------------------------------
    
process
file FSTR             : text ; 
file FSTRC            : text ; 
file Fmem             : text ; 
file Fhex             : text ; 
variable INS          : std_logic_vector(IWWIDTH-1 downto 0);
variable addr         : integer;
variable dbits        : integer;
variable data         : std_logic_vector(8 downto 0);
variable dataw        : std_logic_vector(72 downto 0);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?