OpenCores
URL https://opencores.org/ocsvn/pci_core/pci_core/trunk

Subversion Repositories pci_core

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 6 to Rev 7
    Reverse comparison

Rev 6 → Rev 7

/tags/alpha/vhdl_behav/Ms32pci.vhd
0,0 → 1,827
--===================================================================--
--
-- www.OpenCores.Org - June 2000
-- This model adheres to the GNU public license
--
-- Design units : Master device for PCI Local Bus 33 MHz 32 bits
-- (BoardLevel Simulation model)
-- (Entity and architecture)
--
-- File name : MS32PCI.vhd
--
-- Purpose : The Master device is used to simulate a master
-- device on the PCI-Bus
--
-- Note : This model is modelled after the PCI protocol
-- as described in Xilinx & Altera AppNotes
--
-- Limitations : None known
--
-- Errors : None known
--
-- Library : PCI_Lib.vhd
--
-- Dependencies : IEEE.Std_Logic_1164
--
-- Author : Ovidiu Lupas
-- olupas@opencores.org
--
-- Simulator : ModelSim EE version 5.2 on a Windows95 PC
-- ActiveVHDL 3.1 on a Windows95 PC
--===================================================================--
library ieee,work;
use ieee.Std_Logic_1164.all;
use work.Simulation.all;
use std.textio.all;
use work.PCI_Def.all;
-----------------------------------------------------------------------
-- ENTITY FOR MASTER PCI SIMULATION MODEL --
-----------------------------------------------------------------------
entity MS32PCI is
generic (
cmd_file : string := "PCI.CMD"; -- the commands file
tdelay : Time := 2 ns; -- delay time parameter
tsetup : Time := 7 ns; -- setup time to be checked
thold : Time := 0 ns); -- hold time to be checked
port (
-- Address, Data and Command buses (37)
AD_Bus : inout STD_LOGIC_VECTOR (31 downto 0);
C_BE_Bus : inout STD_LOGIC_VECTOR (3 downto 0);
PAR : inout STD_LOGIC;
-- Interface control signals (6)
FRAME_N : inout STD_LOGIC;
TRDY_N : in STD_LOGIC;
IRDY_N : inout STD_LOGIC;
STOP_N : in STD_LOGIC;
DEVSEL_N : in STD_LOGIC;
IDSEL : in STD_LOGIC;
-- Error reporting signals (2)
PERR_N : inout STD_LOGIC;
SERR_N : inout STD_LOGIC;
-- Arbitration signals (2)
REQ_N : out STD_LOGIC;
GNT_N : in STD_LOGIC;
-- System signals (2)
CLK : in STD_LOGIC;
RST_N : in STD_LOGIC);
end MS32PCI;--================== End of entity ======================--
-----------------------------------------------------------------------
-- Architecture for Master device : PCI bus 33MHZ 32 bit configuration
-----------------------------------------------------------------------
architecture Behavior of MS32PCI is
---------------------------------------------------------------------
-- Signals
---------------------------------------------------------------------
signal parity_now : Std_Logic; -- internal variable (calculate parity)
signal parity_read : Std_Logic; -- internal variable (parity at read)
signal parity_flag : Boolean; -- internal variable (write ON/OFF on line PERR_N)
signal PAR_READ_TEMP : Std_Logic; -- insert or no signal IRDY_N
signal PAR_READ_FLAG : Std_Logic; -- insert or no signal IRDY_N
---------------------------------------------------------------------
-- Variables
---------------------------------------------------------------------
shared variable RESET : Integer;
begin --======================= Architecture ========================--
---------------------------------------------------------------------
-- Process is used to initialize command
---------------------------------------------------------------------
RSTproc : process(RST_N)
begin
if not RST_N'STABLE and RST_N ='0' then
RESET := 1;
end if;
end process;
---------------------------------------------------------------------
-- Implements the parity generation and parity checking over the
-- AD bus and C/BE bus.
-- Also, generates the PERR_N signal, if the computed parity is not
-- equal with PAR signal, when PAR signal is generated by target
---------------------------------------------------------------------
ParGen : process(CLK)
variable PERR_N_TEMP : Std_Logic;
begin
if not CLK'STABLE and CLK = '0' then
PAR <= parity_now after tdelay; -- PAR ='1','0' or 'Z'
PERR_N <= PERR_N_TEMP after tdelay ;
SERR_N <= PERR_N_TEMP ;
PAR_READ_TEMP <= parity_read ;
 
if parity_flag = true then
PAR_READ_FLAG <= '1';
else
PAR_READ_FLAG <= '0';
end if;
if PAR_READ_FLAG = '1' then --
if (PAR = PAR_READ_TEMP) then -- MASTER sets PERR_N
PERR_N <= '1' after tdelay;
else
if PAR_READ_TEMP = 'Z' then
PERR_N <= 'H' after tdelay;
else
PERR_N <= '0' after tdelay;
end if;
end if;
else
PERR_N <= 'H' after tdelay;
end if;
end if;
end process;
---------------------------------------------------------------------
-- MAIN PROCESS FOR MASTER --
---------------------------------------------------------------------
MS32PCI_MAIN : process
variable Data_array : Data_buffer; -- data array
variable data_last_read : Boolean;
variable irdy_start : Integer; -- variable is actualize
variable irdy_loop : Integer;
variable irdy_nr : Integer; -- by command WAITC
variable irdy_insert : Boolean; -- assert or not IRDY_N
------------------------------------------------------------------
-- Procedure is used to initialize MASTER and irdy_** variables --
------------------------------------------------------------------
procedure Init is
begin
RESET := 0;
AD_Bus <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" ; -- Address and Data Bus
C_BE_Bus <= "ZZZZ"; -- Command Bus
PAR <= 'Z';
PERR_N <= 'Z';
REQ_N <= 'H';
SERR_N <= 'H';
irdy_start := 0; -- number of IRDY state
irdy_nr := 0;
irdy_loop := 255;
parity_flag <= false;
if irdy_loop = 0 or irdy_nr = 0 then
irdy_insert := false;
else
irdy_insert := true;
end if;
end Init;
------------------------------------------------------------------
-- This procedure calculate parity of signals address_data(31..0)
-- and c_be(3..0) and return par_bit
------------------------------------------------------------------
procedure PARITY(
address_data : in STD_LOGIC_VECTOR(31 downto 0);
c_be : in STD_LOGIC_VECTOR(3 downto 0);
par_bit : inout STD_LOGIC) is
begin
par_bit := '0';
for I in 0 to 31 loop
par_bit := par_bit xor address_data(I);
end loop;
 
for I in 0 to 3 loop
par_bit := par_bit xor c_be(I);
end loop;
 
if (par_bit = 'X' or par_bit = 'U') then
par_bit := 'Z';
end if;
end PARITY;
--------------------------------------------------------------------------
-- This procedure is used for READ_Bus and WRITE_Bus operation --
--------------------------------------------------------------------------
procedure READ_WRITE(
address : in STD_LOGIC_VECTOR(31 downto 0); -- address
data : in Data_buffer; -- data to write operation
data_nr : in Integer; -- number of data DWORD(32 bit)
bus_cmd : in STD_LOGIC_VECTOR(3 downto 0); -- bus command
bus_sel : in Data_Enable; -- C/BE lines
rd_wr : in STD_LOGIC) is -- select read or write operation
variable data_number : Integer; -- number of data to read and write
variable data_read : Std_Logic_Vector(31 downto 0); -- data read
variable data_old : Std_Logic_Vector(31 downto 0); -- data read old
variable stop : Boolean; -- internal variable (determined by STOP_N)
variable str8 : string(1 to 8);
variable Good2 : Boolean;
variable nr_irdy : Integer; -- duration of IRDY pulse
variable loop_irdy : Integer; -- position of IRDY pulse
variable start_irdy : Integer; -- used for master-abord termination
variable parity_temp : Std_Logic; -- internal variable
variable trdy_stop : Integer; -- internal variable
variable trdy_exit : Boolean; -- internal variable
begin
if GNT_N /= '1' then
wait until FALLING_EDGE(CLK); -- start cycle
end if;
 
while (GNT_N /= '0' and GNT_N /= 'L') and (RESET = 0) loop
wait until FALLING_EDGE(CLK);
AD_Bus(31 downto 0) <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after tdelay;
C_BE_Bus(3 downto 0) <= "ZZZZ" after tdelay;
FRAME_N <= 'Z';-- after tdelay;
IRDY_N <= 'Z' after tdelay;
parity_now <= 'Z' after tdelay;
REQ_N <= '0' after tdelay;
end loop;
 
if (RESET = 0) then
-- exit curent instruction if signal RST_N is active
-- GM
--- acces to the bus has been granted
data_number := data_nr; -- number of DWORDs for transfer
stop := false; --
start_irdy := 3; --
nr_irdy := irdy_nr; -- actualize internal variable
loop_irdy := irdy_loop; -- --"--
irdy_insert := true; -- --"--
trdy_stop := 8; -- wait maximum 8 clock cycles for TRDY
trdy_exit := false;
 
if rd_wr = '1' then -- READ /WRITE CYCLE
--------------------------------------------------------------------
-- BEGIN READ CYCLE --
--------------------------------------------------------------------
-- address phase
AD_Bus(31 downto 0) <= address(31 downto 0) after tdelay; -- set address
C_BE_Bus(3 downto 0) <= bus_cmd(3 downto 0) after tdelay; -- set command
FRAME_N <= '0';-- after tdelay;
IRDY_N <= '1' after tdelay;
parity_flag <= false;
parity_read <= 'Z' after tdelay;
-- calculate parity of address cycle
parity(address(31 downto 0), bus_cmd(3 downto 0), parity_temp);
parity_now <= parity_temp;
 
if GNT_N'Last_Event <= tsetup then -- GNT setup time violation ?
report "GNT setup time violation"
severity Warning;
end if;
wait until FALLING_EDGE(CLK); -- make turnarround cycle
-- GM
REQ_N <= '1';
-- END GM
IRDY_N <= '0' after tdelay;
 
AD_Bus(31 downto 0) <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after tdelay;
C_BE_Bus(3 downto 0) <= bus_sel(1) after tdelay;
parity_now <= 'Z';
wait until FALLING_EDGE(CLK); -- end turnarround cycle
 
-- wait for DEVSEL_N = '0'
-- (implement MASTER-ABORT if TARGET is not responding)
-- wait for the number of IRDY state
while ((start_irdy > 0) and (DEVSEL_N = '1' or DEVSEL_N = 'H' or
DEVSEL_N = 'Z' or DEVSEL_N = 'X') ) loop
start_irdy := start_irdy -1; -- from the begining of read cycle
AD_Bus(31 downto 0) <="ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after tdelay;
C_BE_Bus(3 downto 0) <= bus_sel(1) after tdelay;
wait until FALLING_EDGE(CLK);
end loop;
--- exit cycle if RST_N or STOP_N are active
if RESET =1 or STOP_N = '0' or STOP_N ='L' then
stop := true; -- exit cycle
end if;
 
if DEVSEL_N'Last_Event <= tsetup then
report "DEVSEL_N setup time violation"
severity Warning;
end if;
 
--- inset IRDY_N if loop_irdy =1 and nr_irdy >1
if loop_irdy =1 then
while (nr_irdy > 1) loop
IRDY_N <='1' after tdelay;
nr_irdy := nr_irdy -1 ;
wait until FALLING_EDGE(CLK);
end loop;
IRDY_N <='0' after tdelay;
end if;
-- terminate cycle because DEVSEL_N is anactive
-- (implement command MASTER-ABORT TERMINATION )
if start_irdy = 0 then -- terminate cycle
stop := true;
FRAME_N <='1'; -- after tdelay;
end if;
-- wait until FALLING_EDGE(CLK);
-- repeat until all data are read or STOP_N ='0'
while ((data_number > 0) and (stop = false)) loop -- read cycle
parity_flag <= true;
data_number := data_number -1;
parity_flag <= true;
data_read := data(data_nr - data_number);
if data_number = 0 then
C_BE_Bus(3 downto 0) <=bus_sel(data_nr) after tdelay;
data_read := data(data_nr);
else
C_BE_Bus(3 downto 0) <=bus_sel(data_nr - data_number+1) after tdelay;
data_read := data(data_nr - data_number);
end if;
 
parity_flag <= true;
if data_number =0 then
FRAME_N <='1';-- after tdelay;
end if;
 
-- exit cycle if RST_N or STOP_N are active
if RESET = 1 or STOP_N = '0' or STOP_N = 'L' then
stop := true; -- exit cycle
irdy_insert := false;
end if;
 
if irdy_insert = true and (data_nr - data_number) = loop_irdy then
-- insert IRDY ='1' if insert_trdy =true
while nr_irdy > 1 loop
nr_irdy := nr_irdy -1 ;
IRDY_N <= '1' after tdelay; -- insert IRDY
-- exit cycle if RST_N or STOP_N are active
if RESET = 1 or STOP_N = '0' or STOP_N = 'L' then
stop := true; -- exit cycle
nr_irdy := 1;
end if;
wait until FALLING_EDGE(CLK);
end loop; -- end loop nr_irdy
end if; -- end if irdy_insert
-- IRDY_N <= '0' after tdelay;
if data_number = 0 then
IRDY_N <= '0' after tdelay;
end if;
wait until RISING_EDGE(CLK);
if TRDY_N'Last_Event <= tsetup then -- end of cycle
report "TRDY_N setup time violation"
severity Warning;
end if;
-- wait for TRDY_N = '0' (maxim 8 clock pulse)
while TRDY_N = '1' and trdy_exit = false loop
wait until RISING_EDGE(CLK);
-- wait maxim 8 clock pulse if TRDY is asserted
trdy_stop := trdy_stop -1;
if trdy_stop = 0 then
stop := true;
report "Target is not responding "
severity Warning;
FRAME_N <= '1';-- after tdelay;
IRDY_N <= '1' after tdelay;
trdy_exit := true;
end if;
 
-- exit cycle if RST_N or STOP_N are active
if RESET = 1 or STOP_N = '0' or STOP_N = 'L' then
stop := true; -- exit cycle
trdy_exit := true;
end if;
end loop; -- end loop TRDY_N=1
 
Vec2Hex (data_read,str8,Good2);
report " EXPECTED DATA= "&str8 &""; -- display expected data
 
Vec2Hex (AD_Bus,str8,Good2);
report " READ DATA= "&str8 &""; -- display receive data
 
if AD_Bus'Last_Event <= tsetup then -- end of cycle
report "AD_BUS setup time violation"
severity Warning;
end if;
if ((data_number >0) and (stop =false)) then
wait until FALLING_EDGE(CLK);
end if;
 
wait for thold;
if AD_Bus'Last_Event <= thold then -- end of cycle
report "AD_Bus hold time violation"
severity Warning;
end if;
end loop; -- end loop data_number
 
if RESET =1 or STOP_N ='0' or STOP_N ='L' then
AD_Bus(31 downto 0) <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after tdelay;
C_BE_Bus(3 downto 0) <= "ZZZZ" after tdelay;
FRAME_N <= 'Z';-- after tdelay;
IRDY_N <= 'Z' after tdelay;
parity_now <= 'Z' after tdelay;
REQ_N <= 'H' after tdelay;
parity_flag <= false;
end if;
else
--------------------------------------------------------------------
-- BEGIN WRITE CYCLE --
--------------------------------------------------------------------
-- adress phase
parity_flag <= false;
nr_irdy := nr_irdy;
AD_Bus(31 downto 0) <= address(31 downto 0) after tdelay; -- set address
C_BE_Bus(3 downto 0) <= bus_cmd(3 downto 0)after tdelay; -- set command
FRAME_N <= '0'; -- after tdelay;
IRDY_N <= '1' after tdelay;
parity_read <= 'Z';
parity(address(31 downto 0), bus_cmd(3 downto 0), parity_temp); -- calculate parity of address cycle
parity_now <= parity_temp after tdelay;
wait until FALLING_EDGE(CLK);
-- end adress phase
 
REQ_N <='1';
 
parity_flag <= false;
IRDY_N <= '0' after tdelay;
-- wait for 1 ns;
-- wait for DEVSEL_N = '0'
-- (implement command MASTER-ABORT TERMINATION if TARGET not respond)
while ((start_irdy > 0) and (DEVSEL_N ='H' or DEVSEL_N ='Z' or DEVSEL_N ='X') ) loop -- wait for the number of IRDY state
start_irdy := start_irdy -1; -- from the begining of read cycle
wait until FALLING_EDGE(CLK);
end loop;
 
-- if device not respond then exits the write command
if start_irdy = 0 then -- terminate cycle
stop := true;
FRAME_N <= '1';-- after tdelay;
end if;
 
if DEVSEL_N'Last_Event <= tsetup then
report "DEVSEL_N setup time violation"
severity Warning;
end if;
 
while ((data_number >0) and (stop =false)) loop
-- data phase
data_number := data_number -1;
AD_Bus(31 downto 0) <= data(data_nr - data_number) after tdelay; -- set DATA
C_BE_Bus(3 downto 0) <= bus_sel(data_nr - data_number) after tdelay; -- set BE#s
IRDY_N <= '0' after tdelay;
parity(data(data_nr - data_number), bus_sel(data_nr - data_number), parity_temp); -- calculate parity
parity_now <= parity_temp after tdelay;
-- end data phase
if data_number = 0 then
FRAME_N <= '1';-- after tdelay;
end if;
 
-- exit cycle if RST_N,GNT_N or STOP_N are active
if RESET = 1 or STOP_N= '0' or STOP_N = 'L' then
stop := true; -- exit cycle
end if;
 
wait until RISING_EDGE(CLK);
 
if TRDY_N'Last_Event <= tsetup then -- end of cycle
report "TRDY_N setup time violation"
severity Warning;
end if;
 
-- wait for TRDY_N ='0'
while TRDY_N ='1' and trdy_exit = false loop
wait until RISING_EDGE(CLK);
-- wait maxim 8 clock pulse if TRDY is asserted
trdy_stop := trdy_stop -1;
if trdy_stop = 0 then
stop := true;
report "Target is not responding "
severity Warning;
FRAME_N <= '1';-- after tdelay;
IRDY_N <= '1' after tdelay;
trdy_exit := true;
end if;
 
-- exit cycle if RST_N,GNT_N or STOP_N are active
if RESET = 1 or STOP_N = '0' or STOP_N = 'L' then
stop := true; -- exit cycle
trdy_exit := true;
end if;
end loop; -- end loop TRDY=1
if ((data_number > 0) and (stop = false)) then
wait until FALLING_EDGE(CLK); -- synchronize with PCICLK
end if;
-- insert IRDY_N
if irdy_insert = true and (data_nr -data_number) = loop_irdy
and data_number >0 and (stop =false) then
while nr_irdy > 1 loop
IRDY_N <='1' after tdelay;
nr_irdy := nr_irdy -1 ;
if nr_irdy > 0 then
if data_number > 0 then
C_BE_Bus(3 downto 0) <=bus_sel(data_nr - data_number +1) after tdelay; -- set BE#s
parity(data(data_nr - data_number), bus_sel(data_nr - data_number+1), parity_temp); -- calculate parity
parity_now <= parity_temp after tdelay;
end if;
wait until FALLING_EDGE(CLK);
end if;
 
if RESET = 1 or STOP_N = '0' or STOP_N = 'L' then
stop := true; -- exit cycle
nr_irdy := 1;
end if;
end loop; -- end loop nr_irdy
end if;
report " WRITE DATA= "&str8 &""; -- display write data
end loop; -- end loop start_irdy > 0 ...
 
if RESET = 1 or STOP_N = '0' or STOP_N = 'L' then
AD_Bus(31 downto 0) <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after tdelay;
C_BE_Bus(3 downto 0) <= "ZZZZ" after tdelay;
FRAME_N <= 'Z';-- after tdelay;
IRDY_N <= 'Z' after tdelay;
parity_now <= 'Z' after tdelay;
REQ_N <= 'H' after tdelay;
parity_flag <= false;
end if;
end if; -- end rd_wr = '1'
end if; -- if RST_N ='0' then
end READ_WRITE;
--------------------------------------------------------------------------
-- Procedure implement instruction WRSW --
--------------------------------------------------------------------------
-- Writes single DWORD to memory space!
procedure WRSW(
data : in Data_buffer;
address : inout STD_LOGIC_VECTOR(31 downto 0);
data_number : in Integer;
bus_sel : in Data_Enable) is
variable bus_cmd : STD_LOGIC_VECTOR(3 downto 0);
variable str8,str_8 : string(1 to 8);
variable Good2 : Boolean;
begin
bus_cmd := "0111";
address(1 downto 0) := "00";
Vec2Hex (data(1),str8,Good2);
Vec2Hex (address,str_8,Good2);
report "Write single DWORD to memory space! Address : "&str_8;
READ_WRITE(address,data,1,bus_cmd,bus_sel,'0');
end WRSW;
--------------------------------------------------------------------------
-- Procedure implement instruction RDSW --
--------------------------------------------------------------------------
-- Reads single DWORD from memory space!
procedure RDSW(
data : in Data_buffer;
address : inout STD_LOGIC_VECTOR(31 downto 0);
data_number : in Integer;
bus_sel : in Data_Enable) is
variable bus_cmd : STD_LOGIC_VECTOR(3 downto 0);
variable read_data : Data_buffer;
variable str8,str_8 : string(1 to 8);
variable Good2 : Boolean;
begin
bus_cmd := "0110";
address(1 downto 0) := "00";
Vec2Hex (address,str_8,Good2);
report "Read single DWORD from memory space! Address : "&str_8 ;
READ_WRITE(address,data,1,bus_cmd,bus_sel,'1');
end RDSW;
--------------------------------------------------------------------------
-- Procedure implements instruction WRMW --
--------------------------------------------------------------------------
-- Writes multiple DWORDs to memory space - burst mode
procedure WRMW(
data : in Data_buffer;
address : inout STD_LOGIC_VECTOR(31 downto 0);
data_number : in Integer;
bus_sel : in Data_Enable) is
variable bus_cmd : STD_LOGIC_VECTOR(3 downto 0);
variable str8,str_8 : string(1 to 8);
variable Good2 : Boolean;
begin
bus_cmd := "1111";
address(1 downto 0) := "10";
Vec2Hex (address,str_8,Good2);
report "Write multiple DWORDs to memory space! Address : "&str_8 ;
READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'0');
end WRMW;
--------------------------------------------------------------------------
-- Procedure implements instruction RDMW --
--------------------------------------------------------------------------
-- Reads multiple DWORDs from memory space - burst mode
procedure RDMW(
data : in Data_buffer;
address : inout STD_LOGIC_VECTOR(31 downto 0);
data_number : in Integer;
bus_sel : in Data_Enable) is
variable bus_cmd : STD_LOGIC_VECTOR(3 downto 0);
variable read_data : Data_buffer;
variable str8,str_8 : string(1 to 8);
variable Good2 : Boolean;
begin
bus_cmd := "1100";
address(1 downto 0) := "10";
Vec2Hex (address,str_8,Good2);
report "Read multiple DWORDs from memory space! Address : "&str_8;
READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'1');
end RDMW;
--------------------------------------------------------------------------
-- Procedure implements instruction RDML --
--------------------------------------------------------------------------
-- Reads multiple DWORDs from memory space!
procedure RDML(
data : in Data_buffer;
address : inout STD_LOGIC_VECTOR(31 downto 0);
data_number : in Integer;
bus_sel : in Data_Enable) is
variable bus_cmd: STD_LOGIC_VECTOR(3 downto 0);
variable read_data: Data_buffer;
variable str8,str_8 : string(1 to 8);
variable Good2 : Boolean;
begin
bus_cmd := "1110";
address(1 downto 0) := "00";
Vec2Hex (address,str_8,Good2);
report "Reads multiple DWORDs from memory space! Address : "&str_8;
READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'1');
end RDML;
--------------------------------------------------------------------------
-- Procedure implements instruction WCFG --
--------------------------------------------------------------------------
-- writes configuration
procedure WCFG(
data : in Data_buffer;
address : inout STD_LOGIC_VECTOR(31 downto 0);
data_number : in Integer;
bus_sel : in Data_Enable) is
variable bus_cmd : STD_LOGIC_VECTOR(3 downto 0);
variable read_data : Data_buffer;
variable str8,str_8 : string(1 to 8);
variable Good2 : Boolean;
begin
bus_cmd :="1011";
address(1 downto 0) :="00"; -- linear incrementing
Vec2Hex (address,str_8,Good2);
report "Configuration write! Address : "&str_8;
READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'0');
end WCFG;
--------------------------------------------------------------------------
-- Procedure implements instruction RCFG --
--------------------------------------------------------------------------
-- reads configuration
procedure RCFG(
data : in Data_buffer;
address : inout STD_LOGIC_VECTOR(31 downto 0);
data_number : in Integer;
bus_sel : in Data_Enable) is
variable bus_cmd : STD_LOGIC_VECTOR(3 downto 0);
variable read_data : Data_buffer;
variable str8,str_8 : string(1 to 8);
variable Good2 : Boolean;
begin
bus_cmd :="1010";
address(1 downto 0) :="00";
Vec2Hex (address,str_8,Good2);
report "Configuration read ! Address : "&str_8;
READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'1');
end RCFG;
--------------------------------------------------------------------------
-- Procedure implements instruction WRIO --
--------------------------------------------------------------------------
-- writes data to IO port
procedure WRIO(
data : in Data_buffer;
address : inout STD_LOGIC_VECTOR(31 downto 0);
data_number : in Integer;
bus_sel : in Data_Enable) is
variable bus_cmd : STD_LOGIC_VECTOR(3 downto 0);
variable read_data : Data_buffer;
variable str8,str_8 : string(1 to 8);
variable Good2 : Boolean;
begin
bus_cmd := "0011";
address(1 downto 0) := "00";
Vec2Hex (address,str_8,Good2);
report "Write DWORD to I/O space! Address : "&str_8;
READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'0');
end WRIO;
--------------------------------------------------------------------------
-- Procedure implements instruction RDIO --
--------------------------------------------------------------------------
-- reads data from IO port
procedure RDIO(
data : in Data_buffer;
address : inout STD_LOGIC_VECTOR(31 downto 0);
data_number : in Integer;
bus_sel : in Data_Enable) is
variable bus_cmd : STD_LOGIC_VECTOR(3 downto 0);
variable read_data : Data_buffer;
variable str8,str_8 : string(1 to 8);
variable Good2 : Boolean;
begin
bus_cmd :="0010";
address(1 downto 0) :="00";
Vec2Hex (address,str_8,Good2);
report "Read DWORD from memory space! Address : "&str_8;
READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'1');
end RDIO;
--------------------------------------------------------------------------
-- Procedure implements instruction WAIT --
--------------------------------------------------------------------------
-- waits
procedure CWAT(
data : in Data_buffer;
address : inout STD_LOGIC_VECTOR(31 downto 0);
data_number : in Integer;
bus_sel : in Data_Enable) is
variable bus_cmd : STD_LOGIC_VECTOR(3 downto 0);
variable str8,str_8 : string(1 to 8);
variable Good2 : Boolean;
variable byte7_6,byte5,byte4,byte3_2,byte1,byte0 : Integer;
variable Char7_6,Char5,Char4,Char3_2,Char1,Char0 : Std_Logic_Vector(7 downto 0);
begin
Char7_6 := data(1)(31 downto 24);
irdy_loop := Byte2Int(Char7_6) ;
Char5 := "0000" & data(1)(23 downto 20);
irdy_nr := Byte2Int(Char5) + 1;
Char4 := "0000" & data(1)(19 downto 16);
irdy_start := Byte2Int(Char4);
bus_cmd := "0001";
if irdy_loop = 0 or irdy_nr = 0 then
irdy_insert := false;
else
irdy_insert := true;
end if;
READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'0');
end CWAT;
--------------------------------------------------------------------------
-- Procedure implements instruction EXIT --
--------------------------------------------------------------------------
-- ends the Master's activity by placing in HighZ all the lines
procedure ABRT is
begin
wait until FALLING_EDGE(CLK); -- synchro cycle
Init;
wait;
end ABRT;
--------------------------------------------------------------------------
-- Procedure implements the commands file parser and sequencer --
--------------------------------------------------------------------------
procedure Main_case is
variable Commands : CommandArray(1 to 100);
variable NumCommands : Natural;
variable Good : Boolean;
constant HeaderMsg : String := "Main process:";
constant MsgSeverity : Severity_Level := Failure;
variable ErrFlag : Boolean;
variable PC : Integer;
begin
-- Read/Parse the commands file
FileParser (cmd_file,Commands,NumCommands,ErrFlag);
data_last_read := FALSE;
if ErrFlag then
report HeaderMsg&"Errors found in COMMAND file. Execute halts!!!"
severity Warning;
else
PC := 0;
wait until RST_N = '1';
while PC < NumCommands Loop
if RESET = 1 then
RESET := 0;
PC := 0;
end if;
while RST_N = '0' loop -- RESET signal is active
PC := 0; -- if RST_N ='0' restart simulation
REQ_N <= 'H'; -- request is tri-stated
wait until Rising_Edge(CLK); -- synchro wait
end loop;
if STOP_N = '0' then
report HeaderMsg&"Wait until signal STOP_N ='0' !";
wait until STOP_N = '1';
end if;
REQ_N <= '0';
PC := PC + 1;
case Commands(pc).command is
when "WRSW" =>
WRSW(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
when "RDSW" =>
RDSW(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
when "WRMW" =>
WRMW(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
when "RDMW" =>
RDMW(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
when "RDML" =>
RDML(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
when "WCFG" =>
WCFG(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
when "RCFG" =>
RCFG(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
when "WRIO" =>
WRIO(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
when "RDIO" =>
RDIO(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
when "CWAT" =>
CWAT(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
when "ABRT" => ABRT;
when others => null;
end case;
end loop;
end if;
end Main_Case;
---------------------------------------------------------------------
-- MS32PCI_MAIN : process begins
---------------------------------------------------------------------
begin
Init;
Main_case;
end process;
end Behavior; --================= End of architecture ===============--
-----------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas June 09, 2000 New model
-----------------------------------------------------------------------
 
/tags/alpha/vhdl_behav/Pci_lib.vhd
0,0 → 1,793
--===================================================================--
--
-- www.OpenCores.Org - June 2000
-- This model adheres to the GNU public license
--
-- Design units : Functions and procedures used in models
--
-- File name : PCI_LIB.vhd
--
-- Purpose : type conversion functions, read commands file
-- procedures
--
-- Limitations : None known
--
-- Errors : None known
--
-- Library : PCI_Lib.vhd
--
-- Dependencies : IEEE.Std_Logic_1164
--
-- Author : Ovidiu Lupas
-- olupas@opencores.org
--
-- Simulator : ModelSim EE version 5.2 on a Windows95 PC
-- ActiveVHDL 3.1 on a Windows95 PC
--===================================================================--
-----------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas June 09, 2000 New model
-----------------------------------------------------------------------
library IEEE;
use IEEE.Std_Logic_1164.all;
--
package Simulation is
-- Definition of the CommandType record array which is used to record
-- the commands from the .cmd file
type Data_buffer is array(1 to 256) of Std_Logic_Vector(31 downto 0);
type Data_Enable is array(1 to 256) of Std_Logic_Vector(3 downto 0);
type CommandType is
record
command : string(1 to 4);
addr : Std_Logic_Vector(31 downto 0);
data : Data_buffer;
data_nr : Integer;
enable : Data_Enable;
end record;
-- Definition of the CommandArray type type which can be used for
-- the commands present in .cmd file
type CommandArray is array(positive range <>) of CommandType;
end Simulation; --========== End of package Simulation =============--
--
library IEEE,STD,work;
library work;
use work.Simulation.all;
use IEEE.Std_Logic_1164.all;
use STD.textio.all;
--
package PCI_Def is
--------------------------------------------------------------------
-- convert a character to a value from 0 to 15
--------------------------------------------------------------------
function digit_value(
C : Character)
return integer;
--------------------------------------------------------------------
-- Converts unsigned Std_LOGIC_Vector to Integer, leftmost bit is MSB
-- Error message for unknowns (U, X, W, Z, -), converted to 0
-- Verifies whether vector is too long (> 16 bits)
--------------------------------------------------------------------
function Vec2Int (
Invector : in Std_Logic_Vector(15 downto 0))
return Integer;
--------------------------------------------------------------------
-- Converts unsigned Std_Logic_Vector to Integer, leftmost bit is MSB
-- Error message for unknowns (U, X, W, Z, -), converted to 0
-- Verifies whether vector is too long (> 16 bits)
--------------------------------------------------------------------
function Byte2Int (
Invector : in Std_Logic_Vector(7 downto 0))
return Integer;
--------------------------------------------------------------------
-- Converts unsigned Std_Logic_Vector to Integer, leftmost bit is MSB
-- Error message for unknowns (U, X, W, Z, -), converted to 0
-- Verifies whether vector is too long (> 16 bits)
--------------------------------------------------------------------
procedure Hex2Bit (
C : in Character;
Vector : out Std_Logic_Vector(3 downto 0);
Good : out Boolean);
--------------------------------------------------------------------
-- Converts Hex characters to binary representation
-- Asserts that no unknown value exists at the time of conversion.
--------------------------------------------------------------------
procedure Bit2Hex (
Vector : in Std_Logic_Vector(3 downto 0);
C : out Character;
Good : out Boolean);
--------------------------------------------------------------------
-- Converts bit_vector into a hex string
-- Asserts that no unknown value exists at the time of conversion.
--------------------------------------------------------------------
procedure Vec2Hex (
Value : in Std_Logic_Vector(31 downto 0);
result : out String(1 to 8);
Good : out Boolean);
--------------------------------------------------------------------
-- read a number from the line
-- use this if you have hex numbers that are not in VHDL pound-sign format
--------------------------------------------------------------------
procedure Read (
L : inout Line;
value : out Integer;
radix : in Positive);
--------------------------------------------------------------------
-- reads a hex value and returns a bit_vector value
--------------------------------------------------------------------
procedure ReadHex (
L : inout Line;
Value : out Std_Logic_Vector;
Good : out Boolean;
Enable: out Std_Logic_Vector);
--------------------------------------------------------------------
-- Implements the parsing of the cmd file, which specifies the tasks
-- that are applied to the processor.
--------------------------------------------------------------------
procedure FileParser (
constant file_name : in String;
variable Commands : inout CommandArray;
variable NumCommands : out Natural;
variable ErrFlag : inout Boolean);
end PCI_Def; --============== End of package header =================--
--
library IEEE;
use IEEE.Std_Logic_1164.all;
library std;
use std.textio.all;
--
package body PCI_Def is
--------------------------------------------------------------------
-- convert a character to a value from 0 to 15
--------------------------------------------------------------------
function digit_value (
C : Character)
return integer is
constant not_digit : integer := -999;
begin
if (C ='X') and (C ='x') then
return 15;
end if;
if (C >= '0') and (C <= '9') then
return (Character'pos(C) - Character'pos('0'));
elsif (C >= 'a') and (C <= 'f') then
return (character'pos(c) - character'pos('a') + 10);
elsif (C >= 'A') and (C <= 'F') then
return (character'pos(c) - character'pos('A') + 10);
else
return not_digit;
end if;
end digit_value;
--------------------------------------------------------------------
--------------------------------------------------------------------
function Vec2Int (
InVector : in Std_Logic_Vector(15 downto 0))
return Integer is
constant HeaderMsg : String := "To_Integer:";
constant MsgSeverity : Severity_Level := Warning;
variable Value : Integer := 0;
begin
if InVector = "UUUUUUUUUUUUUUUU" then
report HeaderMsg&"The input vector is of type 'U'. Converted to 0"
severity MsgSeverity;
elsif InVector = "XXXXXXXXXXXXXXXX" then
report HeaderMsg&"The input vector is of type 'X'. Converted to 0"
severity MsgSeverity;
elsif InVector = "WWWWWWWWWWWWWWWW" then
report HeaderMsg&"The input vector is of type 'W'. Converted to 0"
severity MsgSeverity;
elsif InVector = "ZZZZZZZZZZZZZZZZ" then
report HeaderMsg&"The input vector is of type 'Z'. Converted to 0"
severity MsgSeverity;
else
for i in 0 to 15 loop
if (InVector(i) = '1') then
Value := Value + (2**I);
end if;
end loop;
end if;
return Value;
end Vec2Int;
--------------------------------------------------------------------
--------------------------------------------------------------------
function Byte2Int (
InVector : in Std_Logic_Vector(7 downto 0))
return Integer is
constant HeaderMsg : String := "To_Integer:";
constant MsgSeverity : Severity_Level := Warning;
variable Value : Integer := 0;
begin
for i in 0 to 7 loop
if (InVector(i) = '1') then
Value := Value + (2**I);
end if;
end loop;
return Value;
end Byte2Int;
--------------------------------------------------------------------
--------------------------------------------------------------------
procedure Hex2Bit (
C : in Character;
Vector : out Std_Logic_Vector(3 downto 0);
Good : out Boolean) is
variable Good1 : Boolean := false;
constant HeaderMsg : String := "Hex2Bit:";
constant MsgSeverity : Severity_Level := Error;
begin
Good := false;
case C is
when '0' => Vector := "0000"; Good1 := true;
when '1' => Vector := "0001"; Good1 := true;
when '2' => Vector := "0010"; Good1 := true;
when '3' => Vector := "0011"; Good1 := true;
when '4' => Vector := "0100"; Good1 := true;
when '5' => Vector := "0101"; Good1 := true;
when '6' => Vector := "0110"; Good1 := true;
when '7' => Vector := "0111"; Good1 := true;
when '8' => Vector := "1000"; Good1 := true;
when '9' => Vector := "1001"; Good1 := true;
when 'A'|'a' => Vector := "1010"; Good1 := true;
when 'B'|'b' => Vector := "1011"; Good1 := true;
when 'C'|'c' => Vector := "1100"; Good1 := true;
when 'D'|'d' => Vector := "1101"; Good1 := true;
when 'E'|'e' => Vector := "1110"; Good1 := true;
when 'F'|'f' => Vector := "1111"; Good1 := true;
-- extended for std_LOGIC --
when 'U'|'u' => Vector := "UUUU"; Good1 := true;
when 'X'|'x' => Vector := "1111"; Good1 := true;
when 'Z'|'z' => Vector := "ZZZZ"; Good1 := true;
when 'W'|'w' => Vector := "WWWW"; Good1 := true;
when 'L'|'l' => Vector := "LLLL"; Good1 := true;
when 'H'|'h' => Vector := "HHHH"; Good1 := true;
when '-' => Vector := "----"; Good1 := true;
when others => Good1 := false;
end case;
if not Good1 then
Vector := "0000";
report HeaderMsg&"Expected a Hex character (0-F)"
severity MsgSeverity;
end if;
Good := Good1;
end Hex2Bit;
--------------------------------------------------------------------
--------------------------------------------------------------------
procedure Bit2Hex (
Vector : Std_Logic_Vector(3 downto 0);
C : out Character;
Good : out Boolean) is
variable Good1 : Boolean := false;
constant HeaderMsg : String := "Bit2Hex: ";
constant MsgSeverity : Severity_Level := Error;
begin
Good := false;
case Vector is
when x"0" => C := '0'; Good1 := true;
when x"1" => C := '1'; Good1 := true;
when x"2" => C := '2'; Good1 := true;
when x"3" => C := '3'; Good1 := true;
when x"4" => C := '4'; Good1 := true;
when x"5" => C := '5'; Good1 := true;
when x"6" => C := '6'; Good1 := true;
when x"7" => C := '7'; Good1 := true;
when x"8" => C := '8'; Good1 := true;
when x"9" => C := '9'; Good1 := true;
when x"A" => C := 'A'; Good1 := true;
when x"B" => C := 'B'; Good1 := true;
when x"C" => C := 'C'; Good1 := true;
when x"D" => C := 'D'; Good1 := true;
when x"E" => C := 'E'; Good1 := true;
when x"F" => C := 'F'; Good1 := true;
when "ZZZZ" => C := 'Z'; Good1 := true;
when others => Good1 := false;
end case;
if not Good1 then
C := '0';
report HeaderMsg&"Expected a Hex character (0-F)"
severity MsgSeverity;
end if;
Good := Good1;
end Bit2Hex;
--------------------------------------------------------------------
--------------------------------------------------------------------
procedure Vec2Hex (
Value : in Std_Logic_Vector(31 downto 0);
Result : out String(1 to 8);
GOOD : out BOOLEAN) is
variable OK : Boolean;
variable C : Character;
constant NE : Integer := value'length/4; -- number of Hex chars
variable BV : Std_Logic_Vector(value'length-1 downto 0) := Value;
variable Res : String(1 to 8);
constant HeaderMsg : String := "Vec2Hex: ";
constant MsgSeverity : Severity_Level := Error;
begin
if Value'length mod 4 /= 0 then -- Testing if Vector is mod 4
Good := false;
report HeaderMsg&"The length of input vector is not modulo 4!"
severity MsgSeverity;
return;
end if;
Bit2Hex(BV(3 downto 0), C, OK); -- Conversion of the 4 LSB bits
if not OK then
Good := false;
return;
end if;
Res := C & Res(2 to NE); -- Places first Char in Result
for i in 1 to NE-1 loop
Bit2Hex(BV(4*i+3 downto 4*i), C, OK); -- Converts next Char
if not OK then
Good := false;
return;
end if;
Res := Res(1 to i) & C & Res(i+2 to NE);
end loop;
for i in 0 to NE-1 loop
Result (1+i) := Res (NE-i);
end loop;
Good := true;
end Vec2Hex;
--------------------------------------------------------------------
--------------------------------------------------------------------
procedure Read (
L : inout line;
Value : out integer;
Radix : in positive) is
constant not_digit : integer := -999;
variable Digit : integer;
variable Result : integer := 0;
variable Pos : integer;
begin
-- calculate the value
if (L'length <=0 ) then
for i in Pos to L'right loop
digit := digit_value(L(i));
exit when (Digit = not_digit) or (digit >= radix);
Result := Result * Radix + digit;
Pos := Pos + 1;
end loop;
Value := Result;
end if;
end Read;
--------------------------------------------------------------------
--------------------------------------------------------------------
procedure ReadHex (
L : inout Line;
Value : out Std_Logic_Vector;
Good : out Boolean;
Enable : out Std_Logic_Vector) is
variable OK : Boolean;
variable C : Character;
constant NE : Integer := value'length/4;
variable BV : Std_Logic_Vector(value'length-1 downto 0);
variable TEMP : Std_Logic_Vector(value'length-1 downto 0);
variable S : String(1 to NE-1);
constant HeaderMsg : String := "Vec2Hex";
constant MsgSeverity : Severity_Level := Warning;
begin
Enable(3 downto 0) :="0000";
if Value'length mod 4 /= 0 then -- Testing if Vector is mod 4
Good := false;
report HeaderMsg&"The length of input vector is not modulo 4!"
severity MsgSeverity;
return;
end if;
loop
read(L, C, OK); -- Finds the first Hex Char
exit when (((C /= ' ') and (C /= CR) and (C /= HT)) or
(L'length = 0));
end loop;
Hex2Bit(C, BV( 3 downto 0), OK); -- Converts first Hex Char to 4 Bits
if C ='X' or C ='x' then
Enable(3) :='1';
end if;
 
if not OK then
Good := false;
return;
end if;
read(L, S, OK); -- Reads the next three Hex Chars
if not OK then
Good := false;
return;
end if;
for i in 1 to NE-1 loop
if s(i) ='X' or s(i) ='x' then
if i=1 then
Enable(3):='1';
end if;
if i=2 or i=3 then
Enable(2):='1';
end if;
if i=4 or i=5 then
Enable(1):='1';
end if;
if i=6 or i=7 then
Enable(0):='1';
end if;
end if;
Hex2Bit(s(i), BV(4*i+3 downto 4*i), OK); -- Converts to BitVector
if not OK then
Good := false;
return;
end if;
end loop;
Good := true;
-- for byte
if (value'length = 8 ) then
for i in 0 to 3 loop
TEMP(i) := BV(value'length-4+i);
end loop;
for i in 0 to 3 loop
TEMP(i+4) := BV(value'length-8+i);
end loop;
end if;
-- for word
if (value'length = 16 ) then
for i in 0 to 3 loop
TEMP(i) := BV(value'length-4+i);
end loop;
for i in 0 to 3 loop
TEMP(i+4) := BV(value'length-8+i);
end loop;
for i in 0 to 3 loop
TEMP(i+8) := BV(value'length-12+i);
end loop;
for i in 0 to 3 loop
TEMP(i+12) := BV(value'length-16+i);
end loop;
end if;
-- for DWORD
if (value'length =32 ) then
for i in 0 to 3 loop
TEMP(i) := BV(value'length-4+i);
end loop;
for i in 0 to 3 loop
TEMP(i+4) := BV(value'length-8+i);
end loop;
for i in 0 to 3 loop
TEMP(i+8) := BV(value'length-12+i);
end loop;
for i in 0 to 3 loop
TEMP(i+12) := BV(value'length-16+i);
end loop;
for i in 0 to 3 loop
TEMP(i+16) := BV(value'length-20+i);
end loop;
for i in 0 to 3 loop
TEMP(i+20) := BV(value'length-24+i);
end loop;
for i in 0 to 3 loop
TEMP(i+24) := BV(value'length-28+i);
end loop;
for i in 0 to 3 loop
TEMP(i+28) := BV(value'length-32+i);
end loop;
end if;
Value := TEMP;
end ReadHex;
--------------------------------------------------------------------
--------------------------------------------------------------------
procedure FileParser (
constant file_name : in String ;
variable Commands : inout CommandArray;
variable NumCommands : out Natural;
variable ErrFlag : inout Boolean) is
File CmdFile : text;
constant HeaderMsg : String := "FileParser:";
constant MsgSeverity : Severity_Level := Error;
variable L : Line := NULL;
variable Linenum : Natural := 0;
variable LblNum : Natural := 0;
variable CmdNum : Natural := 0;
variable EndOfFile : Boolean := false;
variable Good : Boolean := false;
variable Int : Integer;
variable Tm : Time;
variable C : Character;
variable Addr : Std_Logic_Vector(31 downto 0);
variable Data : Std_Logic_Vector(31 downto 0);
variable Enable : Std_Logic_Vector(3 downto 0);
variable Vect_count : Std_Logic_Vector(7 downto 0);
variable Data_word : Std_Logic_Vector(15 downto 0);
variable Data_byte : Std_Logic_Vector(7 downto 0);
variable str4 : string(1 to 4);
variable count_nr : Integer;
variable count : Integer;
begin
ErrFlag := false;
FILE_OPEN(CmdFile,file_name,READ_MODE);
loop
readline(CmdFile,L);
EndOfFile := endfile(CmdFile);
CmdNum := CmdNum + 1;
LineNum := LineNum + 1;
read(L, str4, Good);
if not Good then
CmdNum := CmdNum-1;
else
case str4 is
when "WRSW" => -- write single word command
readhex(L,Addr,Good,Enable);
if not Good then
report HeaderMsg&"Invalid WRSW command in :"&file_name&", line #"& integer'image(LineNum) &", "&"Address parameter should be 8 hex characters"
severity MsgSeverity;
ErrFlag := true;
else
Good := true;
readhex(L,Data_byte,Good,Enable);
count_nr := Byte2Int(Data_Byte);
count := 0;
for I in 0 to count_nr-1 loop
readhex(L,Data,Good,Enable);
if (Good =true) then
count := count + 1;
commands(CmdNum).command := "WRSW";
commands(CmdNum).addr := Addr;
commands(CmdNum).data(count) := Data;
commands(CmdNum).data_nr := count_nr;
commands(CmdNum).enable(count) := Enable;
else
report HeaderMsg&"Invalid DATA in WRSW command ";
end if;
end loop;
end if;
 
when "RDSW" => -- read single word command
readhex(L,Addr,Good,Enable);
if not Good then
report HeaderMsg&"Invalid RDSW command in :"&file_name&", line #"& integer'image(LineNum) &", "&"Address parameter should be 8 hex characters"
severity MsgSeverity;
ErrFlag := true;
else
Good := true;
readhex(L,Data_byte,Good,Enable);
count_nr :=Byte2Int(Data_Byte);
count := 0;
for I in 0 to count_nr-1 loop
readhex(L,Data,Good,Enable);
if (Good =true) then
count := count + 1;
commands(CmdNum).command := "RDSW";
commands(CmdNum).addr := Addr;
commands(CmdNum).data(count) := Data;
commands(CmdNum).data_nr := count_nr;
commands(CmdNum).enable(count) := Enable;
else
report HeaderMsg&"Invalid DATA in RDSW command ";
end if;
end loop;
end if;
 
when "WRMW" => -- write multiple words command
readhex(L,Addr,Good,Enable);
if not Good then
report HeaderMsg&"Invalid WRMW command in :"&file_name&", line #"& integer'image(LineNum) &", "&"Address parameter should be 8 hex characters"
severity MsgSeverity;
ErrFlag := true;
else
Good := true;
readhex(L,Data_byte,Good,Enable);
count_nr :=Byte2Int(Data_Byte);
count := 0;
for I in 0 to count_nr-1 loop
readhex(L,Data,Good,Enable);
if (Good =true) then
count := count + 1;
commands(CmdNum).command := "WRMW";
commands(CmdNum).addr := Addr;
commands(CmdNum).data(count) := Data;
commands(CmdNum).data_nr := count_nr;
commands(CmdNum).enable(count) := Enable;
else
report HeaderMsg&"Invalid DATA in WRMW command ";
end if;
end loop;
end if;
 
when "RDMW" => -- read multiple words command
readhex(L,Addr,Good,Enable);
if not Good then
report HeaderMsg&"Invalid RDMW command in :"&file_name&", line #"& integer'image(LineNum) &", "&"Address parameter should be 8 hex characters"
severity MsgSeverity;
ErrFlag := true;
else
Good := true;
readhex(L,Data_Byte,Good,Enable);
count_nr :=Byte2Int(Data_Byte);
count := 0;
for I in 0 to count_nr-1 loop
readhex(L,Data,Good,Enable);
if (Good =true) then
count := count + 1;
commands(CmdNum).command := "RDMW";
commands(CmdNum).addr := Addr;
commands(CmdNum).data(count) := Data;
commands(CmdNum).data_nr := count_nr;
commands(CmdNum).enable(count) := Enable;
else
report HeaderMsg&"Invalid DATA in RDMW command ";
end if;
end loop;
end if;
 
when "RDML" => -- read multiple words command
readhex(L,Addr,Good,Enable);
if not Good then
report HeaderMsg&"Invalid RDML command in :"&file_name&", line #"& integer'image(LineNum) &", "&"Address parameter should be 8 hex characters"
severity MsgSeverity;
ErrFlag := true;
else
Good := true;
readhex(L,Data_Byte,Good,Enable);
count_nr :=Byte2Int(Data_Byte);
count := 0;
for I in 0 to count_nr-1 loop
readhex(L,Data,Good,Enable);
if (Good =true) then
count := count + 1;
commands(CmdNum).command := "RDML";
commands(CmdNum).addr := Addr;
commands(CmdNum).data(count) := Data;
commands(CmdNum).data_nr := count_nr;
commands(CmdNum).enable(count) := Enable;
else
report HeaderMsg&"Invalid DATA in RDML command ";
end if;
end loop;
end if;
 
when "WCFG" => -- write to configuration space command
readhex(L,Addr,Good,Enable);
if not Good then
report HeaderMsg&"Invalid WCFG command in :"&file_name&", line #"& integer'image(LineNum) &", "&"Address parameter should be 8 hex characters"
severity MsgSeverity;
ErrFlag := true;
else
Good := true;
readhex(L,Data_byte,Good,Enable);
count_nr :=Byte2Int(Data_Byte);
count := 0;
for I in 0 to count_nr-1 loop
readhex(L,Data,Good,Enable);
if (Good =true) then
count := count + 1;
commands(CmdNum).command := "WCFG";
commands(CmdNum).addr := Addr;
commands(CmdNum).data(count) := Data;
commands(CmdNum).data_nr := count_nr;
commands(CmdNum).enable(count) := Enable;
else
report HeaderMsg&"Invalid DATA in WCFG command ";
end if;
end loop;
end if;
 
when "RCFG" => -- read from configuration space command
readhex(L,Addr,Good,Enable);
if not Good then
report HeaderMsg&"Invalid RCFG command in :"&file_name&", line #"& integer'image(LineNum) &", "&"Address parameter should be 8 hex characters"
severity MsgSeverity;
ErrFlag := true;
else
Good := true;
readhex(L,Data_Byte,Good,Enable);
count_nr :=Byte2Int(Data_Byte);
count := 0;
for I in 0 to count_nr-1 loop
readhex(L,Data,Good,Enable);
if (Good =true) then
count := count + 1;
commands(CmdNum).command := "RCFG";
commands(CmdNum).addr := Addr;
commands(CmdNum).data(count) := Data;
commands(CmdNum).data_nr := count_nr;
commands(CmdNum).enable(count) := Enable;
else
report HeaderMsg&"Invalid DATA in RCFG command ";
end if;
end loop;
end if;
 
when "WRIO" => -- write to I/O space command
readhex(L,Addr,Good,Enable);
if not Good then
report HeaderMsg&"Invalid WRIO command in :"&file_name&", line #"& integer'image(LineNum) &", "&"Address parameter should be 8 hex characters"
severity MsgSeverity;
ErrFlag := true;
else
Good := true;
readhex(L,Data_byte,Good,Enable);
count_nr :=Byte2Int(Data_Byte);
count := 0;
for I in 0 to count_nr-1 loop
readhex(L,Data,Good,Enable);
if (Good = true) then
count := count + 1;
commands(CmdNum).command := "WRIO";
commands(CmdNum).addr := Addr;
commands(CmdNum).data(count) := Data;
commands(CmdNum).data_nr := count_nr;
commands(CmdNum).enable(count) := Enable;
else
report HeaderMsg&"Invalid DATA in WRIO command ";
end if;
end loop;
end if;
 
when "RDIO" => -- read from I/O space command
readhex(L,Addr,Good,Enable);
if not Good then
report HeaderMsg&"Invalid RDIO command in :"&file_name&", line #"& integer'image(LineNum) &", "&"Address parameter should be 8 hex characters"
severity MsgSeverity;
ErrFlag := true;
else
Good := true;
readhex(L,Data_Byte,Good,Enable);
count_nr :=Byte2Int(Data_Byte);
count := 0;
for I in 0 to count_nr-1 loop
readhex(L,Data,Good,Enable);
if (Good = true) then
count := count + 1;
commands(CmdNum).command := "RDIO";
commands(CmdNum).addr := Addr;
commands(CmdNum).data(count) := Data;
commands(CmdNum).data_nr := count_nr;
commands(CmdNum).enable(count) := Enable;
else
report HeaderMsg&"Invalid DATA in RDIO command ";
end if;
end loop;
end if;
 
when "CWAT" =>
readhex(L,Addr,Good,Enable);
if not Good then
report HeaderMsg&"Invalid CWAT command in :"&file_name&", line #"& integer'image(LineNum) &", "&"Address parameter should be 8 hex characters"
severity MsgSeverity;
ErrFlag := true;
else
count_nr :=0;
readhex(L,Data,Good,Enable);
if (Good = true) then
count :=count +1;
commands(CmdNum).command := "WAIT";
commands(CmdNum).addr := Addr;
commands(CmdNum).data(1) := Data;
commands(CmdNum).data_nr := 1;
commands(CmdNum).enable(1) := Enable;
else
report HeaderMsg&"Invalid DATA in CWAT command ";
end if;
end if;
 
when "ABRT" =>
count :=count + 1;
commands(CmdNum).command := "ABRT";
commands(CmdNum).addr := "00000000000000000000000000000000";
commands(CmdNum).data(1) := "00000000000000000000000000000000";
commands(CmdNum).data_nr := 1;
commands(CmdNum).enable(1) := Enable;
 
when others =>
CmdNum := CmdNum -1;
if str4(1 to 2)/= "##" then
report HeaderMsg & "Invalid command in file: "&file_name&", line #"& integer'image(LineNum) &", "& "Unknown command : "& str4 & l(l'left to l'right)
severity error;
ErrFlag := true;
end if;
end case;
end if;
NumCommands := CmdNum;
Exit when EndOfFile;
end loop;
end FileParser;
--------------------------------------------------------------------
--------------------------------------------------------------------
end PCI_Def; --================ End of package body ================--
/tags/alpha/vhdl_behav/Test_pci.vhd
0,0 → 1,226
--===================================================================--
--
-- www.OpenCores.Org - January 2000
-- This model adheres to the GNU public license
--
-- Design units : TestBench for PCI devices.
--
-- File name : Test_PCI.vhd
--
-- Purpose : Implements the test bench for PCI 33 MHz, 32 bit devices.
-- It is included one master device and two target devices.
--
-- There can be used more than one target devices in a
-- design, every device being identified by the three
-- base addresses in generic.
--
--
-- Library : PCI_Lib
--
-- Dependencies : IEEE.Std_Logic_1164
--
-- Limitations : None known
--
-- Errors : None known
--
-- Author : Ovidiu Lupas
-- olupas@opencores.org
--
-- Simulator : ModelSim EE version 5.2 on a Windows95 PC
-- ActiveVHDL 3.1 on a Windows95 PC
--===================================================================--
-----------------------------------------------------------------------
-- Entity for PCI bus Arbiter and CLK generator
-----------------------------------------------------------------------
library ieee,work;
use ieee.Std_Logic_1164.all;
use work.Simulation.all;
use work.PCI_Def.all;
-----------------------------------------------------------------------
-----------------------------------------------------------------------
entity ClkGen is
generic ( tperiod : Time := 30 ns );
port (
REQ_N : in Std_Logic;
GNT_N : out Std_Logic := '1';
RST_N : out Std_Logic;
CLK : out Std_Logic); -- System clock
end ClkGen; --=================== End of entity =====================--
--========================== Architecture ===========================--
architecture BEHAV_ClkGen of ClkGen is
begin--======================== Architecture =================================--
---------------------------------------------------------------------
-- Provide the external clock signal to the processor
---------------------------------------------------------------------
ClkDriver : process
variable clktmp: std_logic := '0';
begin
CLK <= clktmp;
clktmp := not clktmp;
wait for tperiod/2;
end process ClkDriver;
---------------------------------------------------------------------
-- Simulates an external PCI-bus arbiter, which always grants the
-- access to the bus :)
---------------------------------------------------------------------
Arbiter : process(REQ_N)
begin
if Falling_Edge(REQ_N) then
GNT_N <= '0' after 10 ns;
elsif Rising_Edge(REQ_N) then
GNT_N <= '1' after 10 ns;
end if;
end process Arbiter;
---------------------------------------------------------------------
-- Provides the reset signal
---------------------------------------------------------------------
RstGen: process
begin
RST_N <= '0';
wait for 100 ns;
RST_N <= '1';
wait for 400 ns;
end process;
end BEHAV_ClkGen; --============== End of architecture ==============--
-----------------------------------------------------------------------
-- TestBench
-----------------------------------------------------------------------
library ieee,work,std;
use ieee.std_logic_1164.all;
use work.ClkGen;
-----------------------------------------------------------------------
-----------------------------------------------------------------------
entity TESTPCI is
end TESTPCI;
--========================== Architecture ===========================--
architecture stimulus of TESTPCI is
---------------------------------------------------------------------
-- Signal declaration
---------------------------------------------------------------------
signal AD_Bus : Std_Logic_Vector (31 downto 0);
signal C_BE_Bus : Std_Logic_Vector (3 downto 0);
signal PAR : Std_Logic;
signal FRAME_N : Std_Logic;
signal TRDY_N : Std_Logic;
signal IRDY_N : Std_Logic;
signal STOP_N : Std_Logic;
signal DEVSEL_N : Std_Logic;
signal IDSEL : Std_Logic;
signal SEL1 : Std_Logic;
signal SEL2 : Std_Logic;
signal PERR_N : Std_Logic;
signal SERR_N : Std_Logic;
signal REQ_N : Std_Logic;
signal GNT_N : Std_Logic;
signal CLK : Std_Logic;
signal RST_N : Std_Logic;
---------------------------------------------------------------------
-- Component declarations
---------------------------------------------------------------------
component ClkGen
generic ( tperiod : Time := 30 ns );
port (
REQ_N : in Std_Logic;
GNT_N : out Std_Logic;
RST_N : out Std_Logic;
CLK : out Std_Logic); -- System clock
end component;
---------------------------------------------------------------------
---------------------------------------------------------------------
component MS32PCI
generic (
cmd_file : string(1 to 7);
tdelay : Time;
tsetup : Time;
thold : Time);
port (
-- Address, Data and Command buses (37)
AD_Bus : inout STD_LOGIC_VECTOR (31 downto 0);
C_BE_Bus : inout STD_LOGIC_VECTOR (3 downto 0);
PAR : inout STD_LOGIC;
-- Interface control signals (6)
FRAME_N : inout STD_LOGIC;
TRDY_N : in STD_LOGIC;
IRDY_N : inout STD_LOGIC;
STOP_N : in STD_LOGIC;
DEVSEL_N : in STD_LOGIC;
IDSEL : in STD_LOGIC; -- in
-- Error reporting signals (2)
PERR_N : inout STD_LOGIC;
SERR_N : inout STD_LOGIC;
-- Arbitration signals (2)
REQ_N : out STD_LOGIC;
GNT_N : in STD_LOGIC; -- in
-- System signals (2)
CLK : in STD_LOGIC;
RST_N : in STD_LOGIC); --in
end component;
---------------------------------------------------------------------
---------------------------------------------------------------------
component TG32PCI
generic (
devtype : string(1 to 4);
tdelay : Time;
tsetup : Time;
thold : Time;
bamem : Std_Logic_Vector(31 downto 0); -- hex value
baio : Std_Logic_Vector(31 downto 0); -- hex value
bacfg : Std_Logic_Vector(31 downto 0));-- hex value
port (
-- Address, Data and Command buses (37)
AD_Bus : inout Std_Logic_Vector (31 downto 0);
C_BE_Bus : in Std_Logic_Vector (3 downto 0);
PAR : inout Std_Logic;
-- Interface control signals (6)
FRAME_N : in Std_Logic;
TRDY_N : inout Std_Logic;
IRDY_N : in Std_Logic;
STOP_N : out Std_Logic;
DEVSEL_N : inout Std_Logic;
IDSEL : in Std_Logic;
-- Error reporting signals (2)
PERR_N : inout Std_Logic;
SERR_N : inout Std_Logic;
-- System signals (2)
CLK : in Std_Logic;
RST_N : in Std_Logic);
end component;
begin --====================== Architecture =========================--
---------------------------------------------------------------------
-- Component instantiation
---------------------------------------------------------------------
UUT1: MS32PCI
generic map (
"PCI.CMD",0 ns, 7 ns, 5 ns)
port map (
AD_Bus,C_BE_Bus,PAR,FRAME_N,TRDY_N,IRDY_N,STOP_N,DEVSEL_N,
IDSEL,PERR_N,SERR_N,REQ_N,GNT_N,CLK,RST_N);
SEL1 <= AD_Bus(16);
UUT2: TG32PCI
generic map (
"Fast",0 ns,0 ns,0 ns,x"00005000",x"00000800",x"00010CF0")
port map (
AD_Bus => AD_Bus,C_BE_Bus => C_BE_Bus,PAR => PAR,
FRAME_N => FRAME_N,TRDY_N => TRDY_N,IRDY_N => IRDY_N,
STOP_N => STOP_N,DEVSEL_N => DEVSEL_N,IDSEL => SEL1,
PERR_N => PERR_N,SERR_N => SERR_N,CLK => CLK,RST_N => RST_N);
SEL2 <= AD_Bus(17);
UUT3: TG32PCI
generic map (
"Medi",0 ns,7 ns,0 ns,x"00006000",x"00001800",x"00020CF0")
port map (
AD_Bus => AD_Bus,C_BE_Bus => C_BE_Bus,PAR => PAR,
FRAME_N => FRAME_N,TRDY_N => TRDY_N,IRDY_N => IRDY_N,
STOP_N => STOP_N,DEVSEL_N => DEVSEL_N,IDSEL => SEL2,
PERR_N => PERR_N,SERR_N => SERR_N,CLK => CLK,RST_N => RST_N);
GEN: ClkGen port map (
REQ_N,GNT_N,RST_N,CLK);
---------------------------------------------------------------------
end stimulus; --=============== End of architecture =================--
-----------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas June 09, 2000 New model
-----------------------------------------------------------------------
 
/tags/alpha/vhdl_behav/Tg32pci.vhd
0,0 → 1,1283
--===================================================================--
--
-- www.OpenCores.Org - January 2000
-- This model adheres to the GNU public license
--
-- Design units : Target device for PCI Local Bus 33 MHz 32 bits
-- (BoardLevel Simulation model)
-- (Entity and architecture)
--
-- File name : Tg32PCI.vhd
--
-- Purpose : The Target device is used to simulate a target
-- device on the PCI-Bus
--
-- Note : This model is modelled after the PCI protocol
-- as described in Xilinx & Altera AppNotes
--
-- There can be used more than one target devices in a
-- design, every device being identified by the three
-- base addresses in generic.
--
-- Limitations : None known
--
-- Errors : None known
--
-- Library : PCI_Lib.vhd
--
-- Dependencies : IEEE.Std_Logic_1164
--
-- Author : Ovidiu Lupas
-- olupas@opencores.org
--
-- Simulator : ModelSim EE version 5.2 on a Windows95 PC
-- ActiveVHDL 3.1 on a Windows95 PC
--===================================================================--
-----------------------------------------------------------------------
-- Entity for Target device in a PCI bus 33 MHZ 32 bit configuration
-----------------------------------------------------------------------
library ieee,work;
use ieee.Std_Logic_1164.all;
use work.Simulation.all;
use work.PCI_Def.all;
-----------------------------------------------------------------------
-----------------------------------------------------------------------
entity Target32PCI is
generic (
devtype : string(1 to 4); -- type of the device (Fast, Medi, Slow)
tdelay : Time; -- delay time parameter when the device will change
-- data on AD_Bus (referenced to CLK signal)
tsetup : Time;
thold : Time;
bamem : Std_Logic_Vector(31 downto 0); -- base address for memory
baio : Std_Logic_Vector(31 downto 0); -- base address for I/O port
bacfg : Std_Logic_Vector(31 downto 0)); -- base address for cfg space
port (
-- Address, Data and Command buses (37)
AD_Bus : inout Std_Logic_Vector (31 downto 0); -- Address and Data Bus
C_BE_Bus : in Std_Logic_Vector (3 downto 0); -- Command Bus
PAR : inout Std_Logic; --
-- Interface control signals (6)
FRAME_N : in Std_Logic;
TRDY_N : inout Std_Logic;
IRDY_N : in Std_Logic;
STOP_N : out Std_Logic;
DEVSEL_N : inout Std_Logic;
IDSEL : in Std_Logic;
-- Error reporting signals (2)
PERR_N : inout Std_Logic;
SERR_N : inout Std_Logic;
-- System signals (2)
CLK : in Std_Logic;
RST_N : in Std_Logic);
end Target32PCI;--================ End of entity ====================--
-----------------------------------------------------------------------
-- Architecture for Target device PCI bus 33MHZ 32 bit configuration
-----------------------------------------------------------------------
architecture Behavior of Target32PCI is
---------------------------------------------------------------------
-- Definition of Memory type,
---------------------------------------------------------------------
type MEMORY is array(0 to 255) of Std_Logic_Vector(31 downto 0);
---------------------------------------------------------------------
-- Local declarations
---------------------------------------------------------------------
shared variable addr : Std_Logic_Vector (31 downto 0); -- Address
shared variable busaddr : Integer; -- address present on bus
shared variable cfgaddr : Integer; -- current configuration register address
shared variable memaddr : Integer; -- current memory address
shared variable ioaddr : Integer; -- current I/O port address
shared variable IOmem : Memory; -- IOport registers
shared variable Cfgmem : Memory; -- Configuration registers
shared variable Mem : Memory; -- memory locations
shared variable trdywaits : Boolean := false; -- wait enable
shared variable trdy_st,trdy_nr,trdy_loop : Integer := 0;
---------------------------------------------------------------------
-- Signals
---------------------------------------------------------------------
signal cmd : Std_Logic_Vector (3 downto 0); -- Command bus
signal Busy : Std_Logic := '0';
signal IORead : Std_Logic := '0';
signal IOWrite : Std_Logic := '0';
signal MemRead : Std_Logic := '0';
signal MemWrite : Std_Logic := '0';
signal WaitWrite : Std_Logic := '0';
signal CfgRead : Std_Logic := '0';
signal CfgWrite : Std_Logic := '0';
signal FrameEv : Std_Logic := '0';
signal CmdBusReady : Std_Logic := '0';
signal TrnArnd : Std_Logic := '0';
signal DevAddr : Std_Logic := '0';
signal ResFin : Std_Logic := '0';
signal Waits : Std_Logic := '0';
signal Init : Std_Logic := '0';
begin--======================== Architecture ========================--
---------------------------------------------------------------------
-- Initialize the memory contents with zeroes
---------------------------------------------------------------------
Initialize : process
begin
for i in 0 to 255 loop
IOmem(i) := x"00000000";
Mem(i) := x"00000000";
Cfgmem(i) := x"00000000";
end loop;
wait;
end process;
---------------------------------------------------------------------
-- Implements the parity generation and parity checking over the
-- AD bus and C/BE bus.
-- Also, generates the PERR_N signal, if the computed parity is not
-- equal with PAR signal, when PAR signal is generated by master
---------------------------------------------------------------------
Parity : process(CLK,RST_N)
variable parbit : Std_Logic;
variable lastpar : Std_Logic;
variable errbit : Std_Logic;
variable pargen : Boolean := false;
variable errgen : Boolean := false;
variable cmdbus : Std_Logic_Vector(3 downto 0);
variable addrbus : Std_Logic_Vector(31 downto 0);
begin
if (Falling_Edge(RST_N) or RST_N = '0') then
PAR <= 'Z';
PERR_N <= 'Z';
elsif (CLK'Event and CLK = '1') then -- parity computation on every cycle
addrbus := AD_Bus;
cmdbus := C_BE_Bus;
lastpar := parbit;
parbit := '0';
if addrbus /= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" then
for I in 0 to 31 loop
parbit := parbit xor addrbus(i);
end loop;
for I in 0 to 3 loop
parbit := parbit xor cmdbus(I);
end loop;
else
parbit := 'Z';
end if;
if PAR = lastpar then -- PERR computation on every cycle
errbit := '1';
elsif PAR /= lastpar then
errbit := '0';
elsif PAR = 'Z' then
errbit := 'H';
end if;
if ((IORead = '1' or MemRead = '1' or CfgRead = '1') and DevAddr = '1') then
pargen := true;
else
pargen := false;
end if;
elsif (CLK'Event and CLK = '0' and DevAddr = '1') then -- parity generation if necessary
if errgen = true then
PERR_N <= errbit;
else
PERR_N <= 'H';
end if;
if pargen = true then
PAR <= parbit;
errgen := false;
else
PAR <= 'Z';
errgen := true;
end if;
elsif (CLK'Event and CLK = '0' and DevAddr = '0') then --not the selected device
PAR <= 'Z'; -- by the address
PERR_N <= 'H';
SERR_N <= 'Z';
end if;
end process;
---------------------------------------------------------------------
-- Implements the command decoding, to receive commands from master
---------------------------------------------------------------------
Decode : process(CLK,FRAME_N,Busy,DevAddr,cmdBusReady,RST_N)
variable counter : Integer;
variable devdel : Boolean := false;
begin
if (Falling_Edge(RST_N) or RST_N = '0') then
DEVSEL_N <= 'Z';
STOP_N <= 'Z';
Busy <= '0';
elsif (Frame_N'Event and Frame_N = '0') then -- the target device is awakened by
FrameEv <= '1'; -- falling_edge of FRAME signal
counter := 0;
elsif (Busy'Event and Busy = '0') then
IOWrite <= '0';
MemWrite <= '0';
CfgWrite <= '0';
WaitWrite <= '0';
IORead <= '0';
MemRead <= '0';
CfgRead <= '0';
elsif (Busy'Event and Busy = '1') then
if ( IOWrite = '1' or MemWrite = '1' or CfgWrite = '1' or WaitWrite = '1') then
report "Target device is selected for write operations!"
severity Note;
if devtype = "Fast" then
DEVSEL_N <= '0' after 8 ns;
Stop_N <= '1' after 10 ns;
devdel := false;
else
devdel := true;
counter := 0;
end if;
elsif ( IORead = '1' or MemRead = '1' or CfgRead = '1') then
report "Target device is selected for read operations!"
severity Note;
if devtype = "Fast" then
DEVSEL_N <= '0' after 8 ns;
Stop_N <= '1' after 10 ns;
devdel := false;
else
devdel := true;
counter := 0;
end if;
end if;
elsif (DevAddr'Event and DevAddr = '0') then
Busy <= '0';
elsif (cmdBusReady'Event and cmdBusReady = '1') then
TrnArnd <= '0';
elsif (CLK'Event and CLK = '0') then
if Busy = '0' and DevAddr = '1' then -- deselect
DEVSEL_N <= 'H';
STOP_N <= '1';
elsif DevAddr = '0' then -- deselect device
DEVSEL_N <= 'Z';
STOP_N <= 'Z';
end if;
elsif (CLK'Event and CLK = '1') then
if ResFin = '1' then -- memory reserved mode command
if MemWrite = '1' then -- master writes to target memory
if TRDY_N = '0' and IRDY_N = '0' then
Busy <= '0';
ResFin <= '0';
end if;
elsif MemRead = '1' then -- master reads from target memory
if TrnArnd = '0' and TRDY_N = '0' and IRDY_N = '0' then
Busy <= '0';
ResFin <= '0';
end if;
end if;
end if;
if devdel = true then
if devtype = "Medi" then
if counter = 0 then
DEVSEL_N <= '0' after 8 ns;
Stop_N <= '1' after 10 ns;
devdel := false;
end if;
elsif devtype = "Slow" then
if counter = 1 then
DEVSEL_N <= '0' after 8 ns;
Stop_N <= '1' after 10 ns;
devdel := false;
else
counter := counter + 1;
end if;
end if;
end if;
if FRAME_N = '1' then -- end of cycle
assert (IRDY_N = '0')
report "Target device : FRAME signal deassertion error. IRDY is not asserted."
severity Error;
if TRDY_N = '0' and IRDY_N = '0' then -- finish the current cycle
Busy <= '0';
end if;
elsif FrameEv = '1' then -- decoding
FrameEv <= '0';
assert (FRAME_N'Last_Event >= tsetup)
report "Target device : Frame setup time violation in decode cycle!"
severity warning;
assert (AD_Bus'Last_Event >= tsetup)
report "Target device : Address setup time violation in decode cycle!"
severity warning;
assert (C_BE_Bus'Last_Event >= tsetup)
report "Target device : Command setup time violation in decode cycle!"
severity warning;
addr := AD_Bus;
case C_BE_Bus is -- decoding the command bus
when "0001" => -- Special Cycle! Used to transfer from master device the
-- wait states parameters
if (addr(31 downto 8) = bacfg(31 downto 8) and IDSEL ='1') then
WaitWrite <= '1';
DevAddr <= '1';
Busy <= '1';
trdywaits := true;
else -- this device is not the addressed one,
DevAddr <= '0'; -- so it is not responding
trdywaits := false;
end if;
cfgaddr := Byte2Int(addr(7 downto 0));
when "0010" => -- I/O Read! Master reads from target device.
if addr(31 downto 8) = baio(31 downto 8) then
DevAddr <= '1';
Busy <= '1';
IORead <= '1';
TrnArnd <= '1';
ioaddr := Byte2Int(addr(7 downto 0));
else -- this device is not the addressed one,
DevAddr <= '0'; -- so it is not responding
end if;
when "0011" => -- I/O Write! Master writes to target device.
if addr(31 downto 8) = baio(31 downto 8) then
DevAddr <= '1';
Busy <= '1';
IOWrite <= '1';
ioaddr := Byte2Int(addr(7 downto 0));
else -- this device is not the addressed one,
DevAddr <= '0'; -- so it is not responding
end if;
when "1100" => -- Memory Read! Master reads from target device.
if addr(31 downto 8) = bamem(31 downto 8) then
DevAddr <= '1';
Busy <= '1';
MemRead <= '1';
TrnArnd <= '1';
if addr(1 downto 0) = "01" then -- reserved mode
ResFin <= '1';
elsif addr(1 downto 0) = "11" then -- reserved mode
ResFin <= '1';
end if;
memaddr := Byte2Int(addr(7 downto 0));
else -- this device is not the addressed one,
DevAddr <= '0'; -- so it is not responding
end if;
when "1110" => -- Memory Read Line! Master reads from target device.
if addr(31 downto 8) = bamem(31 downto 8) then
DevAddr <= '1';
Busy <= '1';
MemRead <= '1';
TrnArnd <= '1';
if addr(1 downto 0) = "01" then -- reserved mode
ResFin <= '1';
elsif addr(1 downto 0) = "11" then -- reserved mode
ResFin <= '1';
end if;
memaddr := Byte2Int(addr(7 downto 0));
else -- this device is not the addressed one,
DevAddr <= '0'; -- so it is not responding
end if;
when "1111" => -- Memory Write! Master writes to target device.
if addr(31 downto 8) = bamem(31 downto 8) then
DevAddr <= '1';
Busy <= '1';
MemWrite <= '1';
if addr(1 downto 0) = "01" then -- reserved mode
ResFin <= '1';
elsif addr(1 downto 0) = "11" then -- reserved mode
ResFin <= '1';
end if;
memaddr := Byte2Int(addr(7 downto 0));
else -- this device is not the addressed one,
DevAddr <= '0'; -- so it is not responding
end if;
when "0110" => -- Memory Read! Master reads from target device.
if addr(31 downto 8) = bamem(31 downto 8) then
DevAddr <= '1';
Busy <= '1';
MemRead <= '1';
TrnArnd <= '1';
if addr(1 downto 0) = "01" then -- reserved mode
ResFin <= '1';
elsif addr(1 downto 0) = "11" then -- reserved mode
ResFin <= '1';
end if;
memaddr := Byte2Int(addr(7 downto 0));
else -- this device is not the addressed one,
DevAddr <= '0'; -- so it is not responding
end if;
when "0111" => -- Memory Write! Master writes to target device.
if addr(31 downto 8) = bamem(31 downto 8) then
DevAddr <= '1';
Busy <= '1';
MemWrite <= '1';
if addr(1 downto 0) = "01" then -- reserved mode
ResFin <= '1';
elsif addr(1 downto 0) = "11" then -- reserved mode
ResFin <= '1';
end if;
memaddr := Byte2Int(addr(7 downto 0));
else -- this device is not the addressed one,
DevAddr <= '0'; -- so it is not responding
end if;
when "1010" => -- Configuration Read! Master reads from target device.
if (addr(31 downto 8) = bacfg(31 downto 8) and IDSEL = '1') then
if addr(1 downto 0) = "01" then
report "Target device: Type 1 configuration access on bus! Ignored."
severity Note;
elsif addr(1 downto 0) = "00" then
CfgRead <= '1';
TrnArnd <= '1';
DevAddr <= '1';
Busy <= '1';
end if;
cfgaddr := Byte2Int(addr(7 downto 0));
else -- this device is not the addressed one,
DevAddr <= '0'; -- so it is not responding
end if;
when "1011" => -- Configuration Write! Master writes to target device.
if (addr(31 downto 8) = bacfg(31 downto 8) and IDSEL = '1') then
if addr(1 downto 0) = "01" then
report "Target device: Type 1 configuration access on bus! Ignored."
severity Note;
elsif addr(1 downto 0) = "00" then
CfgWrite <= '1';
DevAddr <= '1';
Busy <= '1';
end if;
cfgaddr := Byte2Int(addr(7 downto 0));
else
-- this device is not the addressed one,
DevAddr <= '0'; -- so it is not responding
end if;
when "0100" =>
report "Target device: Reserved Command detected on C/BE bus! Target will not respond."
severity Warning;
when "0101" =>
report "Target device: Reserved Command detected on C/BE bus! Target will not respond."
severity Warning;
when "1000" =>
report "Target device: Reserved Command detected on C/BE bus! Target will not respond."
severity Warning;
when "1001" =>
report "Target device: Reserved Command detected on C/BE bus! Target will not respond."
severity Warning;
when "ZZZZ" => null;
when others =>
report "Target device: Unknown or invalid command on C/BE bus! Ignored."
severity Error;
end case;
end if;
-- elsif (Frame_N'Event and Frame_N = '1') then
end if;
end process;
---------------------------------------------------------------------
-- Implementation of Write command.
-- Master writes to Target device.
---------------------------------------------------------------------
WriteProc : process(CLK,RST_N)
variable waitreg : Std_Logic_Vector(15 downto 0) := x"0000";
variable Char3_2,Char1,Char0 : Std_Logic_Vector(7 downto 0) := x"00";
begin
if (CLK'Event and CLK = '1' and ((IRDY_N = '0' and TRDY_N = '0') or FRAME_N = '1')) then
assert (AD_Bus'Last_Event >= tsetup)
report "Target device : Data setup time violation in decode cycle!"
severity warning;
assert (C_BE_Bus'Last_Event >= tsetup)
report "Target device : Byte Enables setup time violation in decode cycle!"
severity warning;
if (WaitWrite = '1') then
Char3_2 := AD_Bus(15 downto 8);
Char1 := "0000" & AD_Bus(7 downto 4);
Char0 := "0000" & AD_Bus(3 downto 0);
trdy_loop := Byte2Int(Char3_2) ;
trdy_nr := Byte2Int(Char1); -- + 1;
trdy_st := Byte2Int(Char0);
elsif IOWrite = '1' then
-- Master writes to target I/O space
case addr(1 downto 0) is
when "00" =>
if C_BE_Bus = "0000" then
IOmem(ioaddr) := AD_Bus;
elsif C_BE_Bus = "1000" then
IOmem(ioaddr)(23 downto 0) := AD_Bus(23 downto 0);
elsif C_BE_Bus = "0100" then
IOmem(ioaddr)(31 downto 24) := AD_Bus(31 downto 24);
IOmem(ioaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "1100" then
IOmem(ioaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "0010" then
IOmem(ioaddr)(31 downto 16) := AD_Bus(31 downto 16);
IOmem(ioaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1010" then
IOmem(ioaddr)(23 downto 16) := AD_Bus(23 downto 16);
IOmem(ioaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "0110" then
IOmem(ioaddr)(31 downto 24) := AD_Bus(31 downto 24);
IOmem(ioaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1110" then
IOmem(ioaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus(0) = '1' then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when "01" =>
if C_BE_Bus = "0001" then
IOmem(ioaddr)(31 downto 8) := AD_Bus(31 downto 8);
elsif C_BE_Bus = "1001" then
IOmem(ioaddr)(23 downto 8) := AD_Bus(23 downto 8);
elsif C_BE_Bus = "0101" then
IOmem(ioaddr)(31 downto 24) := AD_Bus(31 downto 24);
IOmem(ioaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus = "1101" then
IOmem(ioaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus(1) = '1' then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when "10" =>
if C_BE_Bus = "0011" then
IOmem(ioaddr)(31 downto 16) := AD_Bus(31 downto 16);
elsif C_BE_Bus = "1011" then
IOmem(ioaddr)(23 downto 16) := AD_Bus(23 downto 16);
elsif C_BE_Bus(2) = '1' then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when "11" =>
if C_BE_Bus = "0111" then
IOmem(ioaddr)(31 downto 24) := AD_Bus(31 downto 24);
elsif C_BE_Bus(3) = '1' then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when others =>
null;
end case;
ioaddr := ioaddr + 1;
elsif MemWrite = '1' then
-- Master writes to target memory space
case addr(1 downto 0) is
when "00" => -- linear incrementing mode
if C_BE_Bus = "0000" then
Mem(memaddr) := AD_Bus;
elsif C_BE_Bus = "0001" then
Mem(memaddr)(31 downto 8) := AD_Bus(31 downto 8);
elsif C_BE_Bus = "0010" then
Mem(memaddr)(31 downto 16) := AD_Bus(31 downto 16);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "0011" then
Mem(memaddr)(31 downto 16) := AD_Bus(31 downto 16);
elsif C_BE_Bus = "0100" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "0101" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus = "0110" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "0111" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
elsif C_BE_Bus = "1000" then
Mem(memaddr)(23 downto 0) := AD_Bus(23 downto 0);
elsif C_BE_Bus = "1001" then
Mem(memaddr)(23 downto 8) := AD_Bus(23 downto 8);
elsif C_BE_Bus = "1010" then
Mem(memaddr)(23 downto 16) := AD_Bus(23 downto 16);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1011" then
Mem(memaddr)(23 downto 16) := AD_Bus(23 downto 16);
elsif C_BE_Bus = "1100" then
Mem(memaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "1101" then
Mem(memaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus = "1110" then
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1111" then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
memaddr := memaddr + 1;
when "01" => -- reserved mode (disconnect after first data phase)
if C_BE_Bus = "0000" then
Mem(memaddr) := AD_Bus;
elsif C_BE_Bus = "0001" then
Mem(memaddr)(31 downto 8) := AD_Bus(31 downto 8);
elsif C_BE_Bus = "0010" then
Mem(memaddr)(31 downto 16) := AD_Bus(31 downto 16);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "0011" then
Mem(memaddr)(31 downto 16) := AD_Bus(31 downto 16);
elsif C_BE_Bus = "0100" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "0101" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus = "0110" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "0111" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
elsif C_BE_Bus = "1000" then
Mem(memaddr)(23 downto 0) := AD_Bus(23 downto 0);
elsif C_BE_Bus = "1001" then
Mem(memaddr)(23 downto 8) := AD_Bus(23 downto 8);
elsif C_BE_Bus = "1010" then
Mem(memaddr)(23 downto 16) := AD_Bus(23 downto 16);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1011" then
Mem(memaddr)(23 downto 16) := AD_Bus(23 downto 16);
elsif C_BE_Bus = "1100" then
Mem(memaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "1101" then
Mem(memaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus = "1110" then
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1111" then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when "10" => -- cacheline wrap mode
if C_BE_Bus = "0000" then
Mem(memaddr) := AD_Bus;
elsif C_BE_Bus = "0001" then
Mem(memaddr)(31 downto 8) := AD_Bus(31 downto 8);
elsif C_BE_Bus = "0010" then
Mem(memaddr)(31 downto 16) := AD_Bus(31 downto 16);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "0011" then
Mem(memaddr)(31 downto 16) := AD_Bus(31 downto 16);
elsif C_BE_Bus = "0100" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "0101" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus = "0110" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "0111" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
elsif C_BE_Bus = "1000" then
Mem(memaddr)(23 downto 0) := AD_Bus(23 downto 0);
elsif C_BE_Bus = "1001" then
Mem(memaddr)(23 downto 8) := AD_Bus(23 downto 8);
elsif C_BE_Bus = "1010" then
Mem(memaddr)(23 downto 16) := AD_Bus(23 downto 16);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1011" then
Mem(memaddr)(23 downto 16) := AD_Bus(23 downto 16);
elsif C_BE_Bus = "1100" then
Mem(memaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "1101" then
Mem(memaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus = "1110" then
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1111" then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
memaddr := memaddr + 1;
when "11" => -- reserved mode (disconnect after first data phase)
if C_BE_Bus = "0000" then
Mem(memaddr) := AD_Bus;
elsif C_BE_Bus = "0001" then
Mem(memaddr)(31 downto 8) := AD_Bus(31 downto 8);
elsif C_BE_Bus = "0010" then
Mem(memaddr)(31 downto 16) := AD_Bus(31 downto 16);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "0011" then
Mem(memaddr)(31 downto 16) := AD_Bus(31 downto 16);
elsif C_BE_Bus = "0100" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "0101" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus = "0110" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "0111" then
Mem(memaddr)(31 downto 24) := AD_Bus(31 downto 24);
elsif C_BE_Bus = "1000" then
Mem(memaddr)(23 downto 0) := AD_Bus(23 downto 0);
elsif C_BE_Bus = "1001" then
Mem(memaddr)(23 downto 8) := AD_Bus(23 downto 8);
elsif C_BE_Bus = "1010" then
Mem(memaddr)(23 downto 16) := AD_Bus(23 downto 16);
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1011" then
Mem(memaddr)(23 downto 16) := AD_Bus(23 downto 16);
elsif C_BE_Bus = "1100" then
Mem(memaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "1101" then
Mem(memaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus = "1110" then
Mem(memaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1111" then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when others =>
null;
end case;
elsif CfgWrite = '1' then
-- Master writes to target configuration space
if C_BE_Bus = "0000" then
Cfgmem(cfgaddr) := AD_Bus;
elsif C_BE_Bus = "0001" then
Cfgmem(cfgaddr)(31 downto 8) := AD_Bus(31 downto 8);
elsif C_BE_Bus = "0010" then
Cfgmem(cfgaddr)(31 downto 16) := AD_Bus(31 downto 16);
Cfgmem(cfgaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "0011" then
Cfgmem(cfgaddr)(31 downto 16) := AD_Bus(31 downto 16);
elsif C_BE_Bus = "0100" then
Cfgmem(cfgaddr)(31 downto 24) := AD_Bus(31 downto 24);
Cfgmem(cfgaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "0101" then
Cfgmem(cfgaddr)(31 downto 24) := AD_Bus(31 downto 24);
Cfgmem(cfgaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus = "0110" then
Cfgmem(cfgaddr)(31 downto 24) := AD_Bus(31 downto 24);
Cfgmem(cfgaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "0111" then
Cfgmem(cfgaddr)(31 downto 24) := AD_Bus(31 downto 24);
elsif C_BE_Bus = "1000" then
Cfgmem(cfgaddr)(23 downto 0) := AD_Bus(23 downto 0);
elsif C_BE_Bus = "1001" then
Cfgmem(cfgaddr)(23 downto 8) := AD_Bus(23 downto 8);
elsif C_BE_Bus = "1010" then
Cfgmem(cfgaddr)(23 downto 16) := AD_Bus(23 downto 16);
Cfgmem(cfgaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1011" then
Cfgmem(cfgaddr)(23 downto 16) := AD_Bus(23 downto 16);
elsif C_BE_Bus = "1100" then
Cfgmem(cfgaddr)(15 downto 0) := AD_Bus(15 downto 0);
elsif C_BE_Bus = "1101" then
Cfgmem(cfgaddr)(15 downto 8) := AD_Bus(15 downto 8);
elsif C_BE_Bus = "1110" then
Cfgmem(cfgaddr)(7 downto 0) := AD_Bus(7 downto 0);
elsif C_BE_Bus = "1111" then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
cfgaddr := cfgaddr + 1;
end if;
end if;
end process;
---------------------------------------------------------------------
-- Implementation of Read command.
-- Master read from Target device.
---------------------------------------------------------------------
ReadProc : process(RST_N,CLK,cmdBusReady,IORead,IOWrite,MemRead,MemWrite,CfgRead,CfgWrite)
variable first : Boolean := true;
begin
if (Falling_Edge(RST_N) or RST_N = '0') then
AD_Bus <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
elsif (CLK'Event and CLK = '0') then
cmdBusReady <= '0';
if (first = true or TrnArnd ='1') then
-- Initialize the AD_Bus to avoid bus conflict
AD_Bus <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
first := false;
elsif Init = '1' then
Init <= '0';
AD_Bus <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after tdelay;
end if;
elsif IORead'Event and IORead = '0' then
Init <= '1';
elsif MemRead'Event and MemRead = '0' then
Init <= '1';
elsif CfgRead'Event and CfgRead = '0' then
Init <= '1';
elsif (CLK'Event and CLK = '1' and IRDY_N = '0') then
if (IORead = '1' or MemRead = '1' or CfgRead = '1') then
cmd <= C_BE_Bus; -- read the byte enable command
cmdBusReady <= '1';
end if;
elsif (cmdBusReady'Event and cmdBusReady = '0' and TRDY_N = '0') then
if IORead = '1' then
-- Master reads from target I/O space
case addr(1 downto 0) is
when "00" =>
if cmd = "0000" then
AD_Bus <= IOmem(ioaddr) after tdelay;
elsif cmd = "1000" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 0) <= IOmem(ioaddr)(23 downto 0) after tdelay;
elsif cmd = "0100" then
AD_Bus(31 downto 24) <= IOmem(ioaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
AD_Bus(15 downto 0) <= IOmem(ioaddr)(15 downto 0) after tdelay;
elsif cmd = "1100" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 0) <= IOmem(ioaddr)(15 downto 0) after tdelay;
elsif cmd = "0010" then
AD_Bus(31 downto 16) <= IOmem(ioaddr)(31 downto 16) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
AD_Bus(7 downto 0) <= IOmem(ioaddr)(7 downto 0) after tdelay;
elsif cmd = "1010" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= IOmem(ioaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
AD_Bus(7 downto 0) <= IOmem(ioaddr)(7 downto 0) after tdelay;
elsif cmd = "0110" then
AD_Bus(31 downto 24) <= IOmem(ioaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 8) <= "1111111111111111" after tdelay;
AD_Bus(7 downto 0) <= IOmem(ioaddr)(7 downto 0) after tdelay;
elsif cmd = "1110" then
AD_Bus(31 downto 8) <= "111111111111111111111111" after tdelay;
AD_Bus(7 downto 0) <= IOmem(ioaddr)(7 downto 0) after tdelay;
elsif cmd(0) = '1' then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when "01" =>
if cmd = "0001" then
AD_Bus(31 downto 8) <= IOmem(ioaddr)(31 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1001" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 8) <= IOmem(ioaddr)(23 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "0101" then
AD_Bus(31 downto 24) <= IOmem(ioaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
AD_Bus(15 downto 8) <= IOmem(ioaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1101" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 8) <= IOmem(ioaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd(1) = '1' then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when "10" =>
if cmd = "0011" then
AD_Bus(31 downto 16) <= IOmem(ioaddr)(31 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd = "1011" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= IOmem(ioaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd(2) = '1' then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when "11" =>
if cmd = "0111" then
AD_Bus(31 downto 24) <= IOmem(ioaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 0) <= "111111111111111111111111" after tdelay;
elsif cmd(3) = '1' then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when others =>
null;
end case;
ioaddr := ioaddr + 1;
elsif MemRead = '1' then
-- Master reads from target memory space
case addr(1 downto 0) is
when "00" => -- linear incrementing mode
if cmd = "0000" then
AD_Bus <= Mem(memaddr) after tdelay;
elsif cmd = "0001" then
AD_Bus(31 downto 8) <= Mem(memaddr)(31 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "0010" then
AD_Bus(31 downto 16) <= Mem(memaddr)(31 downto 16) after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
elsif cmd = "0011" then
AD_Bus(31 downto 16) <= Mem(memaddr)(31 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd = "0100" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(15 downto 0) <= Mem(memaddr)(15 downto 0) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
elsif cmd = "0101" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
AD_Bus(15 downto 8) <= Mem(memaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "0110" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 8) <= "1111111111111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "0111" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 0) <= "111111111111111111111111" after tdelay;
elsif cmd = "1000" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 0) <= Mem(memaddr)(23 downto 0) after tdelay;
elsif cmd = "1001" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 8) <= Mem(memaddr)(23 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1010" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= Mem(memaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "1011" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= Mem(memaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd = "1100" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 0) <= Mem(memaddr)(15 downto 0) after tdelay;
elsif cmd = "1101" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 8) <= Mem(memaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1110" then
AD_Bus(31 downto 8) <= "111111111111111111111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "1111" then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
memaddr := memaddr + 1;
when "01" => -- reserved mode (disconnect after first data phase)
if cmd = "0000" then
AD_Bus <= Mem(memaddr) after tdelay;
elsif cmd = "0001" then
AD_Bus(31 downto 8) <= Mem(memaddr)(31 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "0010" then
AD_Bus(31 downto 16) <= Mem(memaddr)(31 downto 16) after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
elsif cmd = "0011" then
AD_Bus(31 downto 16) <= Mem(memaddr)(31 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd = "0100" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(15 downto 0) <= Mem(memaddr)(15 downto 0) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
elsif cmd = "0101" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
AD_Bus(15 downto 8) <= Mem(memaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "0110" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 8) <= "1111111111111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "0111" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 0) <= "111111111111111111111111" after tdelay;
elsif cmd = "1000" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 0) <= Mem(memaddr)(23 downto 0) after tdelay;
elsif cmd = "1001" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 8) <= Mem(memaddr)(23 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1010" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= Mem(memaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "1011" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= Mem(memaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd = "1100" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 0) <= Mem(memaddr)(15 downto 0) after tdelay;
elsif cmd = "1101" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 8) <= Mem(memaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1110" then
AD_Bus(31 downto 8) <= "111111111111111111111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "1111" then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when "10" => -- cacheline wrap mode
if cmd = "0000" then
AD_Bus <= Mem(memaddr) after tdelay;
elsif cmd = "0001" then
AD_Bus(31 downto 8) <= Mem(memaddr)(31 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "0010" then
AD_Bus(31 downto 16) <= Mem(memaddr)(31 downto 16) after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
elsif cmd = "0011" then
AD_Bus(31 downto 16) <= Mem(memaddr)(31 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd = "0100" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(15 downto 0) <= Mem(memaddr)(15 downto 0) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
elsif cmd = "0101" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
AD_Bus(15 downto 8) <= Mem(memaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "0110" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 8) <= "1111111111111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "0111" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 0) <= "111111111111111111111111" after tdelay;
elsif cmd = "1000" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 0) <= Mem(memaddr)(23 downto 0) after tdelay;
elsif cmd = "1001" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 8) <= Mem(memaddr)(23 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1010" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= Mem(memaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "1011" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= Mem(memaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd = "1100" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 0) <= Mem(memaddr)(15 downto 0) after tdelay;
elsif cmd = "1101" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 8) <= Mem(memaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1110" then
AD_Bus(31 downto 8) <= "111111111111111111111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "1111" then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
memaddr := memaddr + 1;
when "11" => -- reserved mode (disconnect after first data phase)
if cmd = "0000" then
AD_Bus <= Mem(memaddr) after tdelay;
elsif cmd = "0001" then
AD_Bus(31 downto 8) <= Mem(memaddr)(31 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "0010" then
AD_Bus(31 downto 16) <= Mem(memaddr)(31 downto 16) after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
elsif cmd = "0011" then
AD_Bus(31 downto 16) <= Mem(memaddr)(31 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd = "0100" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(15 downto 0) <= Mem(memaddr)(15 downto 0) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
elsif cmd = "0101" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
AD_Bus(15 downto 8) <= Mem(memaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "0110" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 8) <= "1111111111111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "0111" then
AD_Bus(31 downto 24) <= Mem(memaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 0) <= "111111111111111111111111" after tdelay;
elsif cmd = "1000" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 0) <= Mem(memaddr)(23 downto 0) after tdelay;
elsif cmd = "1001" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 8) <= Mem(memaddr)(23 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1010" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= Mem(memaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "1011" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= Mem(memaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd = "1100" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 0) <= Mem(memaddr)(15 downto 0) after tdelay;
elsif cmd = "1101" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 8) <= Mem(memaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1110" then
AD_Bus(31 downto 8) <= "111111111111111111111111" after tdelay;
AD_Bus(7 downto 0) <= Mem(memaddr)(7 downto 0) after tdelay;
elsif cmd = "1111" then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
when others =>
null;
end case;
elsif CfgRead = '1' then
-- Master reads from target configuration space
if cmd = "0000" then
AD_Bus <= Cfgmem(cfgaddr) after tdelay;
elsif cmd = "0001" then
AD_Bus(31 downto 8) <= Cfgmem(cfgaddr)(31 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "0010" then
AD_Bus(31 downto 16) <= Cfgmem(cfgaddr)(31 downto 16) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
AD_Bus(7 downto 0) <= Cfgmem(cfgaddr)(7 downto 0) after tdelay;
elsif cmd = "0011" then
AD_Bus(31 downto 16) <= Cfgmem(cfgaddr)(31 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd = "0100" then
AD_Bus(31 downto 24) <= Cfgmem(cfgaddr)(31 downto 24) after tdelay;
AD_Bus(15 downto 0) <= Cfgmem(cfgaddr)(15 downto 0) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
elsif cmd = "0101" then
AD_Bus(31 downto 24) <= Cfgmem(cfgaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 16) <= "11111111" after tdelay;
AD_Bus(15 downto 8) <= Cfgmem(cfgaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "0110" then
AD_Bus(31 downto 24) <= Cfgmem(cfgaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 8) <= "1111111111111111" after tdelay;
AD_Bus(7 downto 0) <= Cfgmem(cfgaddr)(7 downto 0) after tdelay;
elsif cmd = "0111" then
AD_Bus(31 downto 24) <= Cfgmem(cfgaddr)(31 downto 24) after tdelay;
AD_Bus(23 downto 0) <= "111111111111111111111111" after tdelay;
elsif cmd = "1000" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 0) <= Cfgmem(cfgaddr)(23 downto 0) after tdelay;
elsif cmd = "1001" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 8) <= Cfgmem(cfgaddr)(23 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1010" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= Cfgmem(cfgaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 8) <= "11111111" after tdelay;
AD_Bus(7 downto 0) <= Cfgmem(cfgaddr)(7 downto 0) after tdelay;
elsif cmd = "1011" then
AD_Bus(31 downto 24) <= "11111111" after tdelay;
AD_Bus(23 downto 16) <= Cfgmem(cfgaddr)(23 downto 16) after tdelay;
AD_Bus(15 downto 0) <= "1111111111111111" after tdelay;
elsif cmd = "1100" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 0) <= Cfgmem(cfgaddr)(15 downto 0) after tdelay;
elsif cmd = "1101" then
AD_Bus(31 downto 16) <= "1111111111111111" after tdelay;
AD_Bus(15 downto 8) <= Cfgmem(cfgaddr)(15 downto 8) after tdelay;
AD_Bus(7 downto 0) <= "11111111" after tdelay;
elsif cmd = "1110" then
AD_Bus(31 downto 8) <= "111111111111111111111111" after tdelay;
AD_Bus(7 downto 0) <= Cfgmem(cfgaddr)(7 downto 0) after tdelay;
elsif cmd = "1111" then
report "Target device: Byte Enable word not valid !"
severity Error;
end if;
cfgaddr := cfgaddr + 1;
end if;
end if;
end process;
---------------------------------------------------------------------
-- Implements the wait states process.
-- Target generates wait states accordingly to wait states parameters
-- received from master during Special Cycle.
-- Master reads the parameters from commands file.
---------------------------------------------------------------------
WaitProc : process(CLK,FRAME_N,RST_N)
variable counter : Integer;
variable waitcnt : Integer;
variable start : Boolean;
begin
if (Falling_Edge(RST_N) or RST_N = '0') then
TRDY_N <= 'Z';
elsif (FRAME_N'Event and FRAME_N = '0') then
counter := 0;
start := true;
TRDY_N <= '1';
elsif (CLK'Event and CLK = '0') then
if (Busy = '0' and DevAddr = '0') then -- deselect device
TRDY_N <= 'H';
elsif (Busy = '0' and DevAddr = '1') then -- deselect signal
TRDY_N <= '1';
end if;
if (DevAddr = '1' and TrnArnd = '0' and DEVSEL_N = '0') then
if (counter >= trdy_st and start = true and TRDY_N = '1') then
-- finish waitstates at start
TRDY_N <= '0';
start := false;
elsif (counter = trdy_loop and TRDY_N = '0') then
-- random waitstates
TRDY_N <= '1';
waits <= '1';
waitcnt := 1;
elsif (waitcnt = trdy_nr and waits = '1') then
-- finish random waitstates
waits <= '0';
TRDY_N <= '0';
elsif waits = '1' then -- count random waitstates
waitcnt := waitcnt + 1;
end if;
end if;
counter := counter + 1;
end if;
end process;
---------------------------------------------------------------------
-- Implements the assertion process for IRDY_N, FRAME_N, and IDSEL
-- signals.
---------------------------------------------------------------------
AsrtProc : process(CLK,FRAME_N,IRDY_N,IDSEL,AD_Bus)
variable irdevs : Boolean := false;
variable idsevs : Boolean := false;
variable counter : Integer;
begin
if Rising_Edge(CLK) and FRAME_N = '0' and IRDY_N = '1' then
counter := counter + 1;
if counter >= 8 then
report"Target device:IRDY is not asserted within 8 clocks from FRAME assertion!"
severity warning;
end if;
end if;
if AD_Bus'Event then
assert(CLK'Last_Event <= thold)
report"Target device: Address or Data hold time violation!"
severity warning;
end if;
if Rising_Edge(CLK) and DevAddr = '1' then
if irdevs = true then
irdevs := false;
assert(IRDY_N'Last_Event >= tsetup)
report"Target device: IRDY setup time violation in current data transfer!"
severity warning;
end if;
if idsevs = true then
idsevs := false;
assert(IDSEL'Last_Event >= tsetup)
report"Target device: IDSEL setup time violation!"
severity warning;
end if;
if FRAME_N = '0' and IRDY_N = '1' then
counter := counter + 1 ;
end if;
assert (counter <= 8)
report"Target device: IRDY has not been asserted within 8 clocks from FRAME assertion!"
severity warning;
elsif Falling_Edge(FRAME_N) then
counter := 0;
elsif Rising_Edge(FRAME_N) then
assert(CLK'Last_Event <= thold)
report"Target device: FRAME hold time violation in current data transfer!"
severity warning;
elsif Falling_Edge(IRDY_N) and DevAddr = '1' then
irdevs := true;
elsif Rising_Edge(IRDY_N) and DevAddr = '1' then
assert(CLK'Last_Event <= thold)
report"Target device: IRDY hold time violation in current data transfer!"
severity warning;
elsif Rising_Edge(IDSEL) and DevAddr = '1' then
idsevs := true;
elsif Falling_Edge(IDSEL) and DevAddr = '1' then
assert(CLK'Last_Event <= thold)
report"Target device: IDSEL hold time violation!"
severity warning;
end if;
end process;
end Behavior; --================ End of architecture ================--
-----------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas June 09, 2000 New model
-----------------------------------------------------------------------
 
/tags/alpha/vhdl_behav/PCI.CMD
0,0 → 1,59
## CONFIGURE THE FIRST TARGET DEVICE
## WAIT ADDRESS DATA
CWAT 00010CF0 0710FF00
## I/O WRITE DWORD ADDRESS NR. DATA
WRIO 00000850 01 AABBCCDD
##
## I/O READ DWORD ADDRESS NR. DATA
RDIO 00000850 01 AAXXCCDD
##
## I/O WRITE DWORD ADDRESS NR. DATA
WRIO 00000864 04 AABBCCDD EE00AABB CCDDEE00 AABBCCDD
##
## I/O READ DWORD ADDRESS NR. DATA
RDIO 00000864 04 XXBBXXDD EEXXAABB CCDDXX00 XXBBXXDD
##
## CONFIGURE THE SECOND TARGET DEVICE
## WAIT ADDRESS DATA
CWAT 00020CF0 0710FF00
## I/O WRITE DWORD ADDRESS NR. DATA
WRIO 00001850 01 AABBCCDD
##
## I/O READ DWORD ADDRESS NR. DATA
RDIO 00001850 01 AABBCCDD
##
## I/O WRITE DWORD ADDRESS NR. DATA
WRIO 00001860 03 AABBCCDD EE00AABB CCDDEE00
##
## I/O READ DWORD ADDRESS NR. DATA
RDIO 00001860 03 AABBCCDD EE00AABB CCDDEE00
##
## MEMORY WRITE DWORD ADDRESS NR. DATA
WRSW 00005001 01 55AA66BB
##
## MEMORY READ DWORD ADDRESS NR. DATA
RDSW 00005001 01 55AA66BB
##
## MEMORY MULTIPLE WRITE ADDRESS NR. DATA
WRMW 00005000 02 66AA55BB CCDDBBEE
##
## MEMORY MULTIPLE READ ADDRESS NR. DATA
RDMW 00005000 02 XXAAXXBB CCDDXXEE
##
## MEMORY MULTIPLE WRITE ADDRESS NR. DATA
WRMW 00006010 04 66AA55BB CCDDBBEE 33664455 00000001
##
## MEMORY MULTIPLE READ ADDRESS NR. DATA
RDMW 00006010 04 XXAAXXBB CCDDXXEE 33XX4455 00000001
##
## MEMORY READ LINE ADDRESS NR. DATA
## RDML 00005000 04 00000000 00000000 00000000 00000000
##
## CONFIG WRITE DWORD ADDRESS NR. DATA
WCFG 00010CF8 01 20000001
##
## CONFIG READ DWORD ADDRESS NR. DATA
RCFG 00010CF8 01 20000001
##
## EXIT
ABRT
tags/alpha/vhdl_behav/PCI.CMD Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.