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 9 to Rev 10
    Reverse comparison

Rev 9 → Rev 10

tags/alpha/vhdl_behav/PCI.CMD Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: tags/first/diagrams/pci.dia =================================================================== --- tags/first/diagrams/pci.dia (revision 9) +++ tags/first/diagrams/pci.dia (nonexistent) @@ -1,64 +0,0 @@ -VGUIformatVersion 1.004000 - - - - -DEFINE_MODULE: new_unnamed_submodule0 - - DEFINE_DEVICE_INSTANCES: - END_DEFINE_DEVICE_INSTANCES. - - DEFINE_TOPOLOGY: - END_DEFINE_TOPOLOGY. - - -END_DEFINE_MODULE. - - - -DEFINE_MODULE: pci_controller - - PORT_LIST( RST_n, CLK, DEVSEL_n, STOP, FRAME_n, TRDY_n, - IRDY_n, IDSEL, CBE, AD, SERR_n, PERR_n, - PAR ); - - DEFINE_DEVICE_INSTANCES: - trget_machine = Target_machine | 5.600000 4.400000 6.900000 7.300000 - Parity = Parity | 5.600000 2.300000 6.800000 4.200000 - END_DEFINE_DEVICE_INSTANCES. - - DEFINE_TOPOLOGY: - Parity parity_PAR pci_controller PAR half-duplex 0 Std_logic L0 3.500000 2.500000 5.600000 2.500000 - Parity PERR_par_n pci_controller PERR_n half-duplex 0 Std_logic L1 3.500000 2.700000 5.600000 2.700000 - Parity SERR_par_n pci_controller SERR_n half-duplex 0 Std_logic L2 3.500000 2.900000 5.600000 2.900000 - trget_machine AD_trgt Parity AD_trgt simplex 0 Std_logic_vector(31#downto#0) AD 5.600000 3.300000 4.300000 3.300000 4.300000 5.500000 5.600000 5.500000 - pci_controller AD trget_machine AD_trgt half-duplex 0 Std_logic_vector(31#downto#0) AD 5.600000 5.500000 5.300000 5.500000 3.600000 5.500000 - trget_machine CBE_trgt_n Parity CBE_trgt_n simplex 0 Std_logic_vector(3#downto#0) CBE 5.600000 3.700000 4.500000 3.700000 4.500000 5.700000 5.600000 5.700000 - pci_controller CBE trget_machine CBE_trgt_n half-duplex 0 Std_logic_vector(3#downto#0) CBE 5.600000 5.700000 3.600000 5.700000 - pci_controller IDSEL trget_machine IDSEL_trgt simplex 0 Std_logic L7 5.600000 6.000000 3.600000 6.000000 - pci_controller IRDY_n trget_machine IRDY_trgt_n simplex 0 Std_logic L8 5.600000 6.200000 3.600000 6.200000 - trget_machine TRDY_trgt_n pci_controller TRDY_n simplex 0 Std_logic L9 3.600000 6.400000 5.600000 6.400000 - pci_controller FRAME_n trget_machine FRAME_trgt_n simplex 0 Std_logic L10 5.600000 6.600000 3.600000 6.600000 - trget_machine STOP_trgt_n pci_controller STOP simplex 0 Std_logic L11 3.600000 6.800000 5.600000 6.800000 - trget_machine DEVSEL_trgt_n pci_controller DEVSEL_n half-duplex 0 Std_logic L12 3.600000 7.000000 5.600000 7.000000 - pci_controller CLK trget_machine CLK simplex 0 Std_logic CLK 5.600000 4.600000 3.700000 4.600000 - trget_machine CLK Parity CLK simplex 0 Std_logic CLK 5.600000 4.100000 4.800000 4.100000 4.800000 4.600000 5.600000 4.600000 - pci_controller RST_n trget_machine RST_n simplex 0 Std_logic RST_n 5.600000 5.000000 3.700000 5.000000 - trget_machine RST_n Parity RST_n simplex 0 Std_logic RST_n 5.600000 3.900000 4.700000 3.900000 4.700000 5.000000 5.600000 5.000000 - trget_machine ADDR_trgt DEV_NULL simplex 0 Std_logic_vector(LOCALADD#-#1#downto#0) L17 8.900001 4.600000 6.900000 4.600000 - trget_machine DATA_trgt DEV_NULL half-duplex 0 Std_logic_vector(31#downto#0) L17 8.900001 4.900000 6.900000 4.900000 - DEV_NULL unknown_port trget_machine TABORT simplex 0 Std_logic 0 6.900000 7.200000 8.900001 7.200000 - DEV_NULL _ trget_machine TRETRY simplex 0 Std_logic 0 6.900000 7.000000 8.900001 7.000000 - END_DEFINE_TOPOLOGY. - -GENERIC: LOCALADD : integer := 64 - ANNOTATION: 3.821249 8.066763 PCI main block diagram - ANNOTATION: 3.779719 8.403428 PCI OpenCores group - ANNOTATION: 3.788020 8.736729 Jamil Khatib - BOUNDINGBOX: 3.700000 7.600000 7.100000 9.000001 7.100000 7.600000 3.700000 7.600000 3.700000 9.000001 7.100000 9.000001 - -END_DEFINE_MODULE. - - - - Index: trunk/Blocks/pci_parity.vhd =================================================================== --- trunk/Blocks/pci_parity.vhd (revision 9) +++ trunk/Blocks/pci_parity.vhd (nonexistent) @@ -1,144 +0,0 @@ -------------------------------------------------------------------------------- --- Title : PCI Parity core --- Project : PCI target Core -------------------------------------------------------------------------------- --- File : pci_parity.VHD --- Author : Jamil Khatib --- Organization: OpenCores Project --- Created : 2000/04/1 --- Last update : 2000/04/1 --- Platform : --- Simulators : Modelsim 5.3XE / Windows98 --- Synthesizers: webfitter - Leonardo / WindowsNT --- Target : XC9572XL-5-VQ64 - EPF10K100EQC208 Flex10K --- Dependency : -------------------------------------------------------------------------------- --- Description: PCI Parity Core -------------------------------------------------------------------------------- --- Copyright (c) 2000 Jamil Khatib --- --- This VHDL design file is an open design; you can redistribute it and/or --- modify it and/or implement it under the terms of the Openip General Public --- License as it is going to be published by the OpenIPCore Organization and --- any coming versions of this license. --- You can check the draft license at --- http://www.openip.org/oc/license.html --- -------------------------------------------------------------------------------- --- Revisions : --- Revision Number : 1 --- Version : 1.0 --- Date : 1st Apr 2000 --- Modifier : Jamil Khatib (khatib@ieee.org) --- Desccription : Created --- --- Known bugs : Extending the PAR signals to wait states --- : SERR is generated upon local side request only --- : PERR must remain active two clockcycles after the ERR -------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; - -entity parity is - - port ( - -- PCI Interface - CLK : in std_logic; -- PCI clock - AD : in std_logic_vector(31 downto 0); -- PCI AD signal - CBE : in std_logic_vector(3 downto 0); -- C/BE PCI bus signals - PAR : inout std_logic; -- PAR signal - SERR_n : inout std_logic; -- SERR# signal - PERR_n : out std_logic; -- PERR# signal - -- PERR# signal is output only for target - -- Local Interface - ParOperation : in std_logic; -- Parity Operation - -- Drive PAR or check it - Par_oe : in std_logic; -- PAR Output Enable - Locserr_n : in std_logic; -- Local System Error - LocErrRep_n : out std_logic); -- Local Error Report - -- used to report parity errors for local interface - -- and to the configuration register - -end parity; - -library ieee; -use ieee.std_logic_1164.all; -------------------------------------------------------------------------------- -architecture behavior of parity is - -begin -- behavior - -------------------------------------------------------------------------------- --- purpose: Parity Generation --- type : sequential --- inputs : CLK --- outputs: PAR, LocErrRep - Paritygen : process (CLK) - - variable tmp_par : std_logic; -- temporary parity vriable - variable par_q : std_logic; -- Next Par signal - variable perr_q : std_logic; -- Next PERR signal - - begin -- process Paritygen - - if CLK'event and CLK = '1' then -- rising clock edge - if Par_oe = '1' then - -------------------------------------------------------------------------------- --- PAR signal states: --- Idel: when no operation on the current target or master --- PAR = 'Z' , PERR = 'Z' --- Master Read: --- Address phase: --- Master Drives PAR --- Target Drives PERR --- Data phase: --- Target Drives PAR --- Master Drives PERR --- Master write: --- Address and data phase --- Master Drives PAR --- Master Drives PERR -------------------------------------------------------------------------------- --- ParOperation = 1 Calculate and drive PAR Port --- ParOperation = 0 Calculate and report Parity Errors -------------------------------------------------------------------------------- - if ParOperation = '1' then -- Drive PAR signal - - PAR <= par_q; - LocErrRep_n <= perr_q; - PERR_n <= 'Z'; - - else - - PERR_n <= perr_q; - PAR <= 'Z'; - - end if; - --- No of 1's in AD, CBE & PAR must be even - tmp_par := CBE(3) xor CBE(2) xor CBE(1) xor CBE(0); - - for i in AD'range loop - - tmp_par := tmp_par xor AD(i); - - end loop; -- i - - par_q := tmp_par; - - perr_q := tmp_par xor PAR_q; - - else - - PAR <= 'Z'; - PERR_n <= 'Z'; - - end if; - end if; - end process Paritygen; -------------------------------------------------------------------------------- - - SERR_n <= Locserr_n; -------------------------------------------------------------------------------- -end behavior; Index: trunk/TestBench/pci_parity_tb.vhd =================================================================== --- trunk/TestBench/pci_parity_tb.vhd (revision 9) +++ trunk/TestBench/pci_parity_tb.vhd (nonexistent) @@ -1,149 +0,0 @@ -------------------------------------------------------------------------------- --- Title : PCI Parity test bench --- Project : PCI target Core -------------------------------------------------------------------------------- --- File : pci_parity_tb.VHD --- Author : Jamil Khatib --- Organization: OpenCores Project --- Created : 2000/04/1 --- Last update : 2000/04/1 --- Platform : --- Simulators : Modelsim 5.3 XE / Windows98 --- Synthesizers: --- Target : --- Dependency : -------------------------------------------------------------------------------- --- Description: PCI Parity test bench -------------------------------------------------------------------------------- --- Copyright (c) 2000 Jamil Khatib --- --- This VHDL design file is an open design; you can redistribute it and/or --- modify it and/or implement it under the terms of the Openip General Public --- License as it is going to be published by the OpenIPCore Organization and --- any coming versions of this license. --- You can check the draft license at --- http://www.openip.org/oc/license.html --- -------------------------------------------------------------------------------- --- Revisions : --- Revision Number : 1 --- Version : 1.0 --- Date : 2st Apr 2000 --- Modifier : Jamil Khatib (khatib@ieee.org) --- Desccription : Created --- --- Known bugs : -------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; - -entity parity_tb is - -end parity_tb; - -architecture behavior_tb of parity_tb is - component parity - - port ( - -- PCI Interface - CLK : in std_logic; -- PCI clock - AD : in std_logic_vector(31 downto 0); -- PCI AD signal - CBE : in std_logic_vector(3 downto 0); -- C/BE PCI bus signals - PAR : inout std_logic; -- PAR signal - SERR_n : inout std_logic; -- SERR# signal - PERR_n : out std_logic; -- PERR# signal - -- PERR# signal is output only for target - -- Local Interface - ParOperation : in std_logic; -- Parity Operation - -- Drive PAR or check it - Par_oe : in std_logic; -- PAR Output Enable - Locserr_n : in std_logic; -- Local System Error - LocErrRep_n : out std_logic); -- Local Error Report - -- used to report parity errors for local interface - -- and to the configuration register - end component; - - signal clk_tb : std_logic := '0'; -- clock - signal ad_tb : std_logic_vector(31 downto 0); -- AD signal - signal cbe_tb : std_logic_vector(3 downto 0); -- C/BE signal - signal par_tb : std_logic; - signal serr_tb : std_logic; - signal perr_tb : std_logic; - - signal paroperation_tb : std_logic; - signal paroe_tb : std_logic; - signal locserr_tb : std_logic; - signal locerrrep_tb : std_logic; - - signal par_syn_tb : std_logic; - signal serr_syn_tb : std_logic; - signal perr_syn_tb : std_logic; - signal locerrrep_syn_tb : std_logic; - -begin -- behavior_tb - - clk_tb <= not clk_tb after 30 ns; - - UUT : parity - port map ( - CLK => clk_tb, - AD => ad_tb, - CBE => cbe_tb, - PAR => par_tb, - SERR_n => serr_tb, - PERR_n => perr_tb, - ParOperation => paroperation_tb, - Par_oe => paroe_tb, - Locserr_n => locserr_tb, - LocErrRep_n => locerrrep_tb); -------------------------------------------------------------------------------- - - UUT_syn : parity - port map ( - CLK => clk_tb, - AD => ad_tb, - CBE => cbe_tb, - PAR => par_syn_tb, - SERR_n => serr_syn_tb, - PERR_n => perr_syn_tb, - ParOperation => paroperation_tb, - Par_oe => paroe_tb, - Locserr_n => locserr_tb, - LocErrRep_n => locerrrep_syn_tb); - - - par_tb <= transport 'Z' after 0 ns, - '1' after 400 ns; - - par_syn_tb <= transport 'Z' after 0 ns, - '1' after 400 ns; - - ad_tb <= (others => '1'); - cbe_tb <= transport "1111" after 0 ns, - "1000" after 200 ns, - "1111" after 400 ns, - "1000" after 600 ns; - - paroperation_tb <= transport '1' after 0 ns, - '0' after 400 ns; - paroe_tb <= transport '1' after 0 ns, - '0' after 800 ns; - locserr_tb <= '1'; - - - -end behavior_tb; - --- Test bench Configuration -configuration TESTBENCH_FOR_parity of parity_tb is - for behavior_tb - for UUT : parity - use entity work.parity(behavior); - end for; - - for UUT_syn : parity - use entity work.parity(STRUCTURE); - end for; - - end for; -end TESTBENCH_FOR_parity; Index: trunk/vhdl_behav/readme.txt =================================================================== --- trunk/vhdl_behav/readme.txt (revision 9) +++ trunk/vhdl_behav/readme.txt (nonexistent) @@ -1,32 +0,0 @@ -This models are written in VHDL! -Author is Ovidiu Lupas! - -MASTER model -generates PCI compliant signals -checks Target signal compliance with PCI -checks data received from Target for correctness -generates assertion reports if Target signals are not PCI compliant - -TARGET model -generates PCI compliant signals -checks Master signal compliance with PCI -checks data received from Master for correctness -generates assertion reports if Master signals are not PCI compliant - -Description -The models are boardlevel simulation models and are useful in the testing phase -of -the PCI cores design. The models are 32 bit, 33 MHz PCI compliant but are easy -upgradable to 64 bit, 66 MHz. The models are free; you can redistribute them -and/or modify them under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. -The models are distributed in the hope that they will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU General Public License for more details. - -Current Status: -design is available in VHDL from OpenCores CVS via cvsweb -documentation will be available in short time -if needed, easy upgradable to 64 bit, 66 MHz \ No newline at end of file
trunk/vhdl_behav/readme.txt Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/vhdl_behav/Tg32pci.vhd =================================================================== --- trunk/vhdl_behav/Tg32pci.vhd (revision 9) +++ trunk/vhdl_behav/Tg32pci.vhd (nonexistent) @@ -1,1283 +0,0 @@ ---===================================================================-- --- --- 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 TG32PCI 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 TG32PCI; --=================== 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 ------------------------------------------------------------------------ - Index: trunk/vhdl_behav/PCI.CMD =================================================================== --- trunk/vhdl_behav/PCI.CMD (revision 9) +++ trunk/vhdl_behav/PCI.CMD (nonexistent) @@ -1,59 +0,0 @@ -## 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
trunk/vhdl_behav/PCI.CMD Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/vhdl_behav/Ms32pci.vhd =================================================================== --- trunk/vhdl_behav/Ms32pci.vhd (revision 9) +++ trunk/vhdl_behav/Ms32pci.vhd (nonexistent) @@ -1,827 +0,0 @@ ---===================================================================-- --- --- 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 ------------------------------------------------------------------------ - Index: trunk/vhdl_behav/Pci_lib.vhd =================================================================== --- trunk/vhdl_behav/Pci_lib.vhd (revision 9) +++ trunk/vhdl_behav/Pci_lib.vhd (nonexistent) @@ -1,793 +0,0 @@ ---===================================================================-- --- --- 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 ================-- Index: trunk/vhdl_behav/Test_pci.vhd =================================================================== --- trunk/vhdl_behav/Test_pci.vhd (revision 9) +++ trunk/vhdl_behav/Test_pci.vhd (nonexistent) @@ -1,226 +0,0 @@ ---===================================================================-- --- --- 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 ------------------------------------------------------------------------ - Index: trunk/diagrams/pci.dia =================================================================== --- trunk/diagrams/pci.dia (revision 9) +++ trunk/diagrams/pci.dia (nonexistent) @@ -1,64 +0,0 @@ -VGUIformatVersion 1.004000 - - - - -DEFINE_MODULE: new_unnamed_submodule0 - - DEFINE_DEVICE_INSTANCES: - END_DEFINE_DEVICE_INSTANCES. - - DEFINE_TOPOLOGY: - END_DEFINE_TOPOLOGY. - - -END_DEFINE_MODULE. - - - -DEFINE_MODULE: pci_controller - - PORT_LIST( RST_n, CLK, DEVSEL_n, STOP, FRAME_n, TRDY_n, - IRDY_n, IDSEL, CBE, AD, SERR_n, PERR_n, - PAR ); - - DEFINE_DEVICE_INSTANCES: - trget_machine = Target_machine | 5.600000 4.400000 6.900000 7.300000 - Parity = Parity | 5.600000 2.300000 6.800000 4.200000 - END_DEFINE_DEVICE_INSTANCES. - - DEFINE_TOPOLOGY: - Parity parity_PAR pci_controller PAR half-duplex 0 Std_logic L0 3.500000 2.500000 5.600000 2.500000 - Parity PERR_par_n pci_controller PERR_n half-duplex 0 Std_logic L1 3.500000 2.700000 5.600000 2.700000 - Parity SERR_par_n pci_controller SERR_n half-duplex 0 Std_logic L2 3.500000 2.900000 5.600000 2.900000 - trget_machine AD_trgt Parity AD_trgt simplex 0 Std_logic_vector(31#downto#0) AD 5.600000 3.300000 4.300000 3.300000 4.300000 5.500000 5.600000 5.500000 - pci_controller AD trget_machine AD_trgt half-duplex 0 Std_logic_vector(31#downto#0) AD 5.600000 5.500000 5.300000 5.500000 3.600000 5.500000 - trget_machine CBE_trgt_n Parity CBE_trgt_n simplex 0 Std_logic_vector(3#downto#0) CBE 5.600000 3.700000 4.500000 3.700000 4.500000 5.700000 5.600000 5.700000 - pci_controller CBE trget_machine CBE_trgt_n half-duplex 0 Std_logic_vector(3#downto#0) CBE 5.600000 5.700000 3.600000 5.700000 - pci_controller IDSEL trget_machine IDSEL_trgt simplex 0 Std_logic L7 5.600000 6.000000 3.600000 6.000000 - pci_controller IRDY_n trget_machine IRDY_trgt_n simplex 0 Std_logic L8 5.600000 6.200000 3.600000 6.200000 - trget_machine TRDY_trgt_n pci_controller TRDY_n simplex 0 Std_logic L9 3.600000 6.400000 5.600000 6.400000 - pci_controller FRAME_n trget_machine FRAME_trgt_n simplex 0 Std_logic L10 5.600000 6.600000 3.600000 6.600000 - trget_machine STOP_trgt_n pci_controller STOP simplex 0 Std_logic L11 3.600000 6.800000 5.600000 6.800000 - trget_machine DEVSEL_trgt_n pci_controller DEVSEL_n half-duplex 0 Std_logic L12 3.600000 7.000000 5.600000 7.000000 - pci_controller CLK trget_machine CLK simplex 0 Std_logic CLK 5.600000 4.600000 3.700000 4.600000 - trget_machine CLK Parity CLK simplex 0 Std_logic CLK 5.600000 4.100000 4.800000 4.100000 4.800000 4.600000 5.600000 4.600000 - pci_controller RST_n trget_machine RST_n simplex 0 Std_logic RST_n 5.600000 5.000000 3.700000 5.000000 - trget_machine RST_n Parity RST_n simplex 0 Std_logic RST_n 5.600000 3.900000 4.700000 3.900000 4.700000 5.000000 5.600000 5.000000 - trget_machine ADDR_trgt DEV_NULL simplex 0 Std_logic_vector(LOCALADD#-#1#downto#0) L17 8.900001 4.600000 6.900000 4.600000 - trget_machine DATA_trgt DEV_NULL half-duplex 0 Std_logic_vector(31#downto#0) L17 8.900001 4.900000 6.900000 4.900000 - DEV_NULL unknown_port trget_machine TABORT simplex 0 Std_logic 0 6.900000 7.200000 8.900001 7.200000 - DEV_NULL _ trget_machine TRETRY simplex 0 Std_logic 0 6.900000 7.000000 8.900001 7.000000 - END_DEFINE_TOPOLOGY. - -GENERIC: LOCALADD : integer := 64 - ANNOTATION: 3.821249 8.066763 PCI main block diagram - ANNOTATION: 3.779719 8.403428 PCI OpenCores group - ANNOTATION: 3.788020 8.736729 Jamil Khatib - BOUNDINGBOX: 3.700000 7.600000 7.100000 9.000001 7.100000 7.600000 3.700000 7.600000 3.700000 9.000001 7.100000 9.000001 - -END_DEFINE_MODULE. - - - - Index: pci_core/trunk/vhdl_behav/readme.txt =================================================================== --- pci_core/trunk/vhdl_behav/readme.txt (nonexistent) +++ pci_core/trunk/vhdl_behav/readme.txt (revision 10) @@ -0,0 +1,32 @@ +This models are written in VHDL! +Author is Ovidiu Lupas! + +MASTER model +generates PCI compliant signals +checks Target signal compliance with PCI +checks data received from Target for correctness +generates assertion reports if Target signals are not PCI compliant + +TARGET model +generates PCI compliant signals +checks Master signal compliance with PCI +checks data received from Master for correctness +generates assertion reports if Master signals are not PCI compliant + +Description +The models are boardlevel simulation models and are useful in the testing phase +of +the PCI cores design. The models are 32 bit, 33 MHz PCI compliant but are easy +upgradable to 64 bit, 66 MHz. The models are free; you can redistribute them +and/or modify them under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. +The models are distributed in the hope that they will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +Current Status: +design is available in VHDL from OpenCores CVS via cvsweb +documentation will be available in short time +if needed, easy upgradable to 64 bit, 66 MHz \ No newline at end of file
pci_core/trunk/vhdl_behav/readme.txt Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: pci_core/trunk/vhdl_behav/Tg32pci.vhd =================================================================== --- pci_core/trunk/vhdl_behav/Tg32pci.vhd (nonexistent) +++ pci_core/trunk/vhdl_behav/Tg32pci.vhd (revision 10) @@ -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 TG32PCI 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 TG32PCI; --=================== 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 +----------------------------------------------------------------------- + Index: pci_core/trunk/vhdl_behav/Ms32pci.vhd =================================================================== --- pci_core/trunk/vhdl_behav/Ms32pci.vhd (nonexistent) +++ pci_core/trunk/vhdl_behav/Ms32pci.vhd (revision 10) @@ -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 +----------------------------------------------------------------------- + Index: pci_core/trunk/vhdl_behav/Pci_lib.vhd =================================================================== --- pci_core/trunk/vhdl_behav/Pci_lib.vhd (nonexistent) +++ pci_core/trunk/vhdl_behav/Pci_lib.vhd (revision 10) @@ -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 ================-- Index: pci_core/trunk/vhdl_behav/Test_pci.vhd =================================================================== --- pci_core/trunk/vhdl_behav/Test_pci.vhd (nonexistent) +++ pci_core/trunk/vhdl_behav/Test_pci.vhd (revision 10) @@ -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 +----------------------------------------------------------------------- + Index: pci_core/trunk/vhdl_behav/PCI.CMD =================================================================== --- pci_core/trunk/vhdl_behav/PCI.CMD (nonexistent) +++ pci_core/trunk/vhdl_behav/PCI.CMD (revision 10) @@ -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
pci_core/trunk/vhdl_behav/PCI.CMD Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: pci_core/trunk/TestBench/pci_parity_tb.vhd =================================================================== --- pci_core/trunk/TestBench/pci_parity_tb.vhd (nonexistent) +++ pci_core/trunk/TestBench/pci_parity_tb.vhd (revision 10) @@ -0,0 +1,149 @@ +------------------------------------------------------------------------------- +-- Title : PCI Parity test bench +-- Project : PCI target Core +------------------------------------------------------------------------------- +-- File : pci_parity_tb.VHD +-- Author : Jamil Khatib +-- Organization: OpenCores Project +-- Created : 2000/04/1 +-- Last update : 2000/04/1 +-- Platform : +-- Simulators : Modelsim 5.3 XE / Windows98 +-- Synthesizers: +-- Target : +-- Dependency : +------------------------------------------------------------------------------- +-- Description: PCI Parity test bench +------------------------------------------------------------------------------- +-- Copyright (c) 2000 Jamil Khatib +-- +-- This VHDL design file is an open design; you can redistribute it and/or +-- modify it and/or implement it under the terms of the Openip General Public +-- License as it is going to be published by the OpenIPCore Organization and +-- any coming versions of this license. +-- You can check the draft license at +-- http://www.openip.org/oc/license.html +-- +------------------------------------------------------------------------------- +-- Revisions : +-- Revision Number : 1 +-- Version : 1.0 +-- Date : 2st Apr 2000 +-- Modifier : Jamil Khatib (khatib@ieee.org) +-- Desccription : Created +-- +-- Known bugs : +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; + +entity parity_tb is + +end parity_tb; + +architecture behavior_tb of parity_tb is + component parity + + port ( + -- PCI Interface + CLK : in std_logic; -- PCI clock + AD : in std_logic_vector(31 downto 0); -- PCI AD signal + CBE : in std_logic_vector(3 downto 0); -- C/BE PCI bus signals + PAR : inout std_logic; -- PAR signal + SERR_n : inout std_logic; -- SERR# signal + PERR_n : out std_logic; -- PERR# signal + -- PERR# signal is output only for target + -- Local Interface + ParOperation : in std_logic; -- Parity Operation + -- Drive PAR or check it + Par_oe : in std_logic; -- PAR Output Enable + Locserr_n : in std_logic; -- Local System Error + LocErrRep_n : out std_logic); -- Local Error Report + -- used to report parity errors for local interface + -- and to the configuration register + end component; + + signal clk_tb : std_logic := '0'; -- clock + signal ad_tb : std_logic_vector(31 downto 0); -- AD signal + signal cbe_tb : std_logic_vector(3 downto 0); -- C/BE signal + signal par_tb : std_logic; + signal serr_tb : std_logic; + signal perr_tb : std_logic; + + signal paroperation_tb : std_logic; + signal paroe_tb : std_logic; + signal locserr_tb : std_logic; + signal locerrrep_tb : std_logic; + + signal par_syn_tb : std_logic; + signal serr_syn_tb : std_logic; + signal perr_syn_tb : std_logic; + signal locerrrep_syn_tb : std_logic; + +begin -- behavior_tb + + clk_tb <= not clk_tb after 30 ns; + + UUT : parity + port map ( + CLK => clk_tb, + AD => ad_tb, + CBE => cbe_tb, + PAR => par_tb, + SERR_n => serr_tb, + PERR_n => perr_tb, + ParOperation => paroperation_tb, + Par_oe => paroe_tb, + Locserr_n => locserr_tb, + LocErrRep_n => locerrrep_tb); +------------------------------------------------------------------------------- + + UUT_syn : parity + port map ( + CLK => clk_tb, + AD => ad_tb, + CBE => cbe_tb, + PAR => par_syn_tb, + SERR_n => serr_syn_tb, + PERR_n => perr_syn_tb, + ParOperation => paroperation_tb, + Par_oe => paroe_tb, + Locserr_n => locserr_tb, + LocErrRep_n => locerrrep_syn_tb); + + + par_tb <= transport 'Z' after 0 ns, + '1' after 400 ns; + + par_syn_tb <= transport 'Z' after 0 ns, + '1' after 400 ns; + + ad_tb <= (others => '1'); + cbe_tb <= transport "1111" after 0 ns, + "1000" after 200 ns, + "1111" after 400 ns, + "1000" after 600 ns; + + paroperation_tb <= transport '1' after 0 ns, + '0' after 400 ns; + paroe_tb <= transport '1' after 0 ns, + '0' after 800 ns; + locserr_tb <= '1'; + + + +end behavior_tb; + +-- Test bench Configuration +configuration TESTBENCH_FOR_parity of parity_tb is + for behavior_tb + for UUT : parity + use entity work.parity(behavior); + end for; + + for UUT_syn : parity + use entity work.parity(STRUCTURE); + end for; + + end for; +end TESTBENCH_FOR_parity; Index: pci_core/trunk/Blocks/pci_parity.vhd =================================================================== --- pci_core/trunk/Blocks/pci_parity.vhd (nonexistent) +++ pci_core/trunk/Blocks/pci_parity.vhd (revision 10) @@ -0,0 +1,144 @@ +------------------------------------------------------------------------------- +-- Title : PCI Parity core +-- Project : PCI target Core +------------------------------------------------------------------------------- +-- File : pci_parity.VHD +-- Author : Jamil Khatib +-- Organization: OpenCores Project +-- Created : 2000/04/1 +-- Last update : 2000/04/1 +-- Platform : +-- Simulators : Modelsim 5.3XE / Windows98 +-- Synthesizers: webfitter - Leonardo / WindowsNT +-- Target : XC9572XL-5-VQ64 - EPF10K100EQC208 Flex10K +-- Dependency : +------------------------------------------------------------------------------- +-- Description: PCI Parity Core +------------------------------------------------------------------------------- +-- Copyright (c) 2000 Jamil Khatib +-- +-- This VHDL design file is an open design; you can redistribute it and/or +-- modify it and/or implement it under the terms of the Openip General Public +-- License as it is going to be published by the OpenIPCore Organization and +-- any coming versions of this license. +-- You can check the draft license at +-- http://www.openip.org/oc/license.html +-- +------------------------------------------------------------------------------- +-- Revisions : +-- Revision Number : 1 +-- Version : 1.0 +-- Date : 1st Apr 2000 +-- Modifier : Jamil Khatib (khatib@ieee.org) +-- Desccription : Created +-- +-- Known bugs : Extending the PAR signals to wait states +-- : SERR is generated upon local side request only +-- : PERR must remain active two clockcycles after the ERR +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; + +entity parity is + + port ( + -- PCI Interface + CLK : in std_logic; -- PCI clock + AD : in std_logic_vector(31 downto 0); -- PCI AD signal + CBE : in std_logic_vector(3 downto 0); -- C/BE PCI bus signals + PAR : inout std_logic; -- PAR signal + SERR_n : inout std_logic; -- SERR# signal + PERR_n : out std_logic; -- PERR# signal + -- PERR# signal is output only for target + -- Local Interface + ParOperation : in std_logic; -- Parity Operation + -- Drive PAR or check it + Par_oe : in std_logic; -- PAR Output Enable + Locserr_n : in std_logic; -- Local System Error + LocErrRep_n : out std_logic); -- Local Error Report + -- used to report parity errors for local interface + -- and to the configuration register + +end parity; + +library ieee; +use ieee.std_logic_1164.all; +------------------------------------------------------------------------------- +architecture behavior of parity is + +begin -- behavior + +------------------------------------------------------------------------------- +-- purpose: Parity Generation +-- type : sequential +-- inputs : CLK +-- outputs: PAR, LocErrRep + Paritygen : process (CLK) + + variable tmp_par : std_logic; -- temporary parity vriable + variable par_q : std_logic; -- Next Par signal + variable perr_q : std_logic; -- Next PERR signal + + begin -- process Paritygen + + if CLK'event and CLK = '1' then -- rising clock edge + if Par_oe = '1' then + +------------------------------------------------------------------------------- +-- PAR signal states: +-- Idel: when no operation on the current target or master +-- PAR = 'Z' , PERR = 'Z' +-- Master Read: +-- Address phase: +-- Master Drives PAR +-- Target Drives PERR +-- Data phase: +-- Target Drives PAR +-- Master Drives PERR +-- Master write: +-- Address and data phase +-- Master Drives PAR +-- Master Drives PERR +------------------------------------------------------------------------------- +-- ParOperation = 1 Calculate and drive PAR Port +-- ParOperation = 0 Calculate and report Parity Errors +------------------------------------------------------------------------------- + if ParOperation = '1' then -- Drive PAR signal + + PAR <= par_q; + LocErrRep_n <= perr_q; + PERR_n <= 'Z'; + + else + + PERR_n <= perr_q; + PAR <= 'Z'; + + end if; + +-- No of 1's in AD, CBE & PAR must be even + tmp_par := CBE(3) xor CBE(2) xor CBE(1) xor CBE(0); + + for i in AD'range loop + + tmp_par := tmp_par xor AD(i); + + end loop; -- i + + par_q := tmp_par; + + perr_q := tmp_par xor PAR_q; + + else + + PAR <= 'Z'; + PERR_n <= 'Z'; + + end if; + end if; + end process Paritygen; +------------------------------------------------------------------------------- + + SERR_n <= Locserr_n; +------------------------------------------------------------------------------- +end behavior; Index: pci_core/trunk/diagrams/pci.dia =================================================================== --- pci_core/trunk/diagrams/pci.dia (nonexistent) +++ pci_core/trunk/diagrams/pci.dia (revision 10) @@ -0,0 +1,64 @@ +VGUIformatVersion 1.004000 + + + + +DEFINE_MODULE: new_unnamed_submodule0 + + DEFINE_DEVICE_INSTANCES: + END_DEFINE_DEVICE_INSTANCES. + + DEFINE_TOPOLOGY: + END_DEFINE_TOPOLOGY. + + +END_DEFINE_MODULE. + + + +DEFINE_MODULE: pci_controller + + PORT_LIST( RST_n, CLK, DEVSEL_n, STOP, FRAME_n, TRDY_n, + IRDY_n, IDSEL, CBE, AD, SERR_n, PERR_n, + PAR ); + + DEFINE_DEVICE_INSTANCES: + trget_machine = Target_machine | 5.600000 4.400000 6.900000 7.300000 + Parity = Parity | 5.600000 2.300000 6.800000 4.200000 + END_DEFINE_DEVICE_INSTANCES. + + DEFINE_TOPOLOGY: + Parity parity_PAR pci_controller PAR half-duplex 0 Std_logic L0 3.500000 2.500000 5.600000 2.500000 + Parity PERR_par_n pci_controller PERR_n half-duplex 0 Std_logic L1 3.500000 2.700000 5.600000 2.700000 + Parity SERR_par_n pci_controller SERR_n half-duplex 0 Std_logic L2 3.500000 2.900000 5.600000 2.900000 + trget_machine AD_trgt Parity AD_trgt simplex 0 Std_logic_vector(31#downto#0) AD 5.600000 3.300000 4.300000 3.300000 4.300000 5.500000 5.600000 5.500000 + pci_controller AD trget_machine AD_trgt half-duplex 0 Std_logic_vector(31#downto#0) AD 5.600000 5.500000 5.300000 5.500000 3.600000 5.500000 + trget_machine CBE_trgt_n Parity CBE_trgt_n simplex 0 Std_logic_vector(3#downto#0) CBE 5.600000 3.700000 4.500000 3.700000 4.500000 5.700000 5.600000 5.700000 + pci_controller CBE trget_machine CBE_trgt_n half-duplex 0 Std_logic_vector(3#downto#0) CBE 5.600000 5.700000 3.600000 5.700000 + pci_controller IDSEL trget_machine IDSEL_trgt simplex 0 Std_logic L7 5.600000 6.000000 3.600000 6.000000 + pci_controller IRDY_n trget_machine IRDY_trgt_n simplex 0 Std_logic L8 5.600000 6.200000 3.600000 6.200000 + trget_machine TRDY_trgt_n pci_controller TRDY_n simplex 0 Std_logic L9 3.600000 6.400000 5.600000 6.400000 + pci_controller FRAME_n trget_machine FRAME_trgt_n simplex 0 Std_logic L10 5.600000 6.600000 3.600000 6.600000 + trget_machine STOP_trgt_n pci_controller STOP simplex 0 Std_logic L11 3.600000 6.800000 5.600000 6.800000 + trget_machine DEVSEL_trgt_n pci_controller DEVSEL_n half-duplex 0 Std_logic L12 3.600000 7.000000 5.600000 7.000000 + pci_controller CLK trget_machine CLK simplex 0 Std_logic CLK 5.600000 4.600000 3.700000 4.600000 + trget_machine CLK Parity CLK simplex 0 Std_logic CLK 5.600000 4.100000 4.800000 4.100000 4.800000 4.600000 5.600000 4.600000 + pci_controller RST_n trget_machine RST_n simplex 0 Std_logic RST_n 5.600000 5.000000 3.700000 5.000000 + trget_machine RST_n Parity RST_n simplex 0 Std_logic RST_n 5.600000 3.900000 4.700000 3.900000 4.700000 5.000000 5.600000 5.000000 + trget_machine ADDR_trgt DEV_NULL simplex 0 Std_logic_vector(LOCALADD#-#1#downto#0) L17 8.900001 4.600000 6.900000 4.600000 + trget_machine DATA_trgt DEV_NULL half-duplex 0 Std_logic_vector(31#downto#0) L17 8.900001 4.900000 6.900000 4.900000 + DEV_NULL unknown_port trget_machine TABORT simplex 0 Std_logic 0 6.900000 7.200000 8.900001 7.200000 + DEV_NULL _ trget_machine TRETRY simplex 0 Std_logic 0 6.900000 7.000000 8.900001 7.000000 + END_DEFINE_TOPOLOGY. + +GENERIC: LOCALADD : integer := 64 + ANNOTATION: 3.821249 8.066763 PCI main block diagram + ANNOTATION: 3.779719 8.403428 PCI OpenCores group + ANNOTATION: 3.788020 8.736729 Jamil Khatib + BOUNDINGBOX: 3.700000 7.600000 7.100000 9.000001 7.100000 7.600000 3.700000 7.600000 3.700000 9.000001 7.100000 9.000001 + +END_DEFINE_MODULE. + + + + Index: pci_core/trunk =================================================================== --- pci_core/trunk (nonexistent) +++ pci_core/trunk (revision 10)
pci_core/trunk Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: pci_core/web_uploads =================================================================== --- pci_core/web_uploads (nonexistent) +++ pci_core/web_uploads (revision 10)
pci_core/web_uploads Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: pci_core/branches =================================================================== --- pci_core/branches (nonexistent) +++ pci_core/branches (revision 10)
pci_core/branches Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: pci_core/tags/alpha/vhdl_behav/Ms32pci.vhd =================================================================== --- pci_core/tags/alpha/vhdl_behav/Ms32pci.vhd (nonexistent) +++ pci_core/tags/alpha/vhdl_behav/Ms32pci.vhd (revision 10) @@ -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 +----------------------------------------------------------------------- + Index: pci_core/tags/alpha/vhdl_behav/Pci_lib.vhd =================================================================== --- pci_core/tags/alpha/vhdl_behav/Pci_lib.vhd (nonexistent) +++ pci_core/tags/alpha/vhdl_behav/Pci_lib.vhd (revision 10) @@ -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 ================-- Index: pci_core/tags/alpha/vhdl_behav/Test_pci.vhd =================================================================== --- pci_core/tags/alpha/vhdl_behav/Test_pci.vhd (nonexistent) +++ pci_core/tags/alpha/vhdl_behav/Test_pci.vhd (revision 10) @@ -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 +----------------------------------------------------------------------- + Index: pci_core/tags/alpha/vhdl_behav/Tg32pci.vhd =================================================================== --- pci_core/tags/alpha/vhdl_behav/Tg32pci.vhd (nonexistent) +++ pci_core/tags/alpha/vhdl_behav/Tg32pci.vhd (revision 10) @@ -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 +----------------------------------------------------------------------- + Index: pci_core/tags/alpha/vhdl_behav/PCI.CMD =================================================================== --- pci_core/tags/alpha/vhdl_behav/PCI.CMD (nonexistent) +++ pci_core/tags/alpha/vhdl_behav/PCI.CMD (revision 10) @@ -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
pci_core/tags/alpha/vhdl_behav/PCI.CMD Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: pci_core/tags/first/diagrams/pci.dia =================================================================== --- pci_core/tags/first/diagrams/pci.dia (nonexistent) +++ pci_core/tags/first/diagrams/pci.dia (revision 10) @@ -0,0 +1,64 @@ +VGUIformatVersion 1.004000 + + + + +DEFINE_MODULE: new_unnamed_submodule0 + + DEFINE_DEVICE_INSTANCES: + END_DEFINE_DEVICE_INSTANCES. + + DEFINE_TOPOLOGY: + END_DEFINE_TOPOLOGY. + + +END_DEFINE_MODULE. + + + +DEFINE_MODULE: pci_controller + + PORT_LIST( RST_n, CLK, DEVSEL_n, STOP, FRAME_n, TRDY_n, + IRDY_n, IDSEL, CBE, AD, SERR_n, PERR_n, + PAR ); + + DEFINE_DEVICE_INSTANCES: + trget_machine = Target_machine | 5.600000 4.400000 6.900000 7.300000 + Parity = Parity | 5.600000 2.300000 6.800000 4.200000 + END_DEFINE_DEVICE_INSTANCES. + + DEFINE_TOPOLOGY: + Parity parity_PAR pci_controller PAR half-duplex 0 Std_logic L0 3.500000 2.500000 5.600000 2.500000 + Parity PERR_par_n pci_controller PERR_n half-duplex 0 Std_logic L1 3.500000 2.700000 5.600000 2.700000 + Parity SERR_par_n pci_controller SERR_n half-duplex 0 Std_logic L2 3.500000 2.900000 5.600000 2.900000 + trget_machine AD_trgt Parity AD_trgt simplex 0 Std_logic_vector(31#downto#0) AD 5.600000 3.300000 4.300000 3.300000 4.300000 5.500000 5.600000 5.500000 + pci_controller AD trget_machine AD_trgt half-duplex 0 Std_logic_vector(31#downto#0) AD 5.600000 5.500000 5.300000 5.500000 3.600000 5.500000 + trget_machine CBE_trgt_n Parity CBE_trgt_n simplex 0 Std_logic_vector(3#downto#0) CBE 5.600000 3.700000 4.500000 3.700000 4.500000 5.700000 5.600000 5.700000 + pci_controller CBE trget_machine CBE_trgt_n half-duplex 0 Std_logic_vector(3#downto#0) CBE 5.600000 5.700000 3.600000 5.700000 + pci_controller IDSEL trget_machine IDSEL_trgt simplex 0 Std_logic L7 5.600000 6.000000 3.600000 6.000000 + pci_controller IRDY_n trget_machine IRDY_trgt_n simplex 0 Std_logic L8 5.600000 6.200000 3.600000 6.200000 + trget_machine TRDY_trgt_n pci_controller TRDY_n simplex 0 Std_logic L9 3.600000 6.400000 5.600000 6.400000 + pci_controller FRAME_n trget_machine FRAME_trgt_n simplex 0 Std_logic L10 5.600000 6.600000 3.600000 6.600000 + trget_machine STOP_trgt_n pci_controller STOP simplex 0 Std_logic L11 3.600000 6.800000 5.600000 6.800000 + trget_machine DEVSEL_trgt_n pci_controller DEVSEL_n half-duplex 0 Std_logic L12 3.600000 7.000000 5.600000 7.000000 + pci_controller CLK trget_machine CLK simplex 0 Std_logic CLK 5.600000 4.600000 3.700000 4.600000 + trget_machine CLK Parity CLK simplex 0 Std_logic CLK 5.600000 4.100000 4.800000 4.100000 4.800000 4.600000 5.600000 4.600000 + pci_controller RST_n trget_machine RST_n simplex 0 Std_logic RST_n 5.600000 5.000000 3.700000 5.000000 + trget_machine RST_n Parity RST_n simplex 0 Std_logic RST_n 5.600000 3.900000 4.700000 3.900000 4.700000 5.000000 5.600000 5.000000 + trget_machine ADDR_trgt DEV_NULL simplex 0 Std_logic_vector(LOCALADD#-#1#downto#0) L17 8.900001 4.600000 6.900000 4.600000 + trget_machine DATA_trgt DEV_NULL half-duplex 0 Std_logic_vector(31#downto#0) L17 8.900001 4.900000 6.900000 4.900000 + DEV_NULL unknown_port trget_machine TABORT simplex 0 Std_logic 0 6.900000 7.200000 8.900001 7.200000 + DEV_NULL _ trget_machine TRETRY simplex 0 Std_logic 0 6.900000 7.000000 8.900001 7.000000 + END_DEFINE_TOPOLOGY. + +GENERIC: LOCALADD : integer := 64 + ANNOTATION: 3.821249 8.066763 PCI main block diagram + ANNOTATION: 3.779719 8.403428 PCI OpenCores group + ANNOTATION: 3.788020 8.736729 Jamil Khatib + BOUNDINGBOX: 3.700000 7.600000 7.100000 9.000001 7.100000 7.600000 3.700000 7.600000 3.700000 9.000001 7.100000 9.000001 + +END_DEFINE_MODULE. + + + + Index: pci_core/tags =================================================================== --- pci_core/tags (nonexistent) +++ pci_core/tags (revision 10)
pci_core/tags Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ##

powered by: WebSVN 2.1.0

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