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

Subversion Repositories pci_to_wb

[/] [pci_to_wb/] [trunk/] [PCI_to_WB.vhd] - Rev 2

Compare with Previous | Blame | View Log

--+------------------------------------------------------------------+
--|																						|
--|	PCI_TARGET -> Wishbone_MASTER interface (PCI_to_WB) v1.9			|
--|																						|
--|	The first, original PCI module is from:								|
--|	Ben Jackson, http://www.ben.com/minipci/verilog.php				|
--|																						|
--|	The second, modified module "pci_mini" is from:						|
--|	Istvan Nagy, buenos@freemail.hu											|
--|																						|
--|																						|
--|	DOWNLOADED FROM OPENCORES. License = LGPL.							|
--|																						|
--+------------------------------------------------------------------+
--|	I used the code of the original pci_mini module to create		|
--|	a PCI to WB interface with direct read accesses (not				|
--|	like before, where data would be available only on					|
--|	a second PCI read) because that didn't work in my system.		|
--|	Thanks to Ben Jackson and Istvan Nagy for their works!			|
--|	I would not have been able to design such a core without			|
--|	the provided code base.														|
--|	Nelson Scheja (Lord_Nelson@opencores.org).							|
--+------------------------------------------------------------------+----------------------------+
-- ########## General info ##########
 
-- The core implements a 16 MB memory image which is relocable on the WB bus:
-- WB_address = 4 * baseaddr + PCI_addr[23:2], where baseaddr is the WB image relocation
-- register (BAR0).
-- Only Dword aligned Dword accesses are allowed on the PCI. This way we can have access to the
-- full 32 bit WB address space through a 16 MB PCI window. The addressing on the WB bus is
-- Dword addressing, while on the PCI bus, it is byte addressing: PCI_addr / 4 = WB_address.
-- That means, when the PCI address is increasing by 4 ( = 4 Bytes = 1 Dword), the WB address
-- is increasing by 1 ( = 1 Dword, too).
 
-- Nearly full Wishbone compatible; single exception is master arbitration (through signals
-- wb_req and wb_gnt) which is not implemented.
 
-- (Remember, most PCI signals are active low, so I call them "asserted" when they are 0!
-- Only exceptions are clk, idsel and par, which are active high.)
 
-- The duration of a complete PCI cycle depends on the PCI command and the reaction time of the
-- PCI master and the addressed WB slave. Generally, Memory Reads need the most time to complete
-- (as the data path is the longest), and Config Writes are fastest.
 
 
-- ########## PCI bus support ##########
 
-- Intended PCI operation mode is 33 MHz, 32 bit.
 
-- Supported PCI commands are Config Read / Write, Memory Read / Write. Only single Dword
-- accesses are supported. (As the cbe bits are ignored for MemRead and MemWrite, a full DWord
-- is always transferred on these commands. Still, Byte or Word accesses are not recommended.)
 
-- The core supports only single reads / writes, that means only one data phase per PCI
-- cycle. Bursts are not allowed. In the first data phase, it asserts the stop signal
-- together with trdy to enforce a so-called "target initiated disconnect". This makes sure
-- that the PCI master will never try to extend a cycle past the first data phase.
 
-- When no WB response has been sent for WB_MAX_LAT clock cycles during a MemRead or MemWrite,
-- the core signals "Target-Abort" to the master. WB_MAX_LAT is user-definable in the range
-- from 0h to Fh.
 
-- DEVSEL timing is "fast". That means, devsel will be asserted the next clock edge after the
-- assertion of frame.
 
-- Parity of outgoing data is generated (one clock cycle after driving the ad lines). Parity
-- check of incoming address/data is not implemented. Thus, perr is held in high impedance the
-- whole time.
 
-- System Error indication is not implemented, thus serr is high impedance the whole time.
 
 
-- ########## Wishbone bus support ##########
 
-- Implemented Wishbone signals: wb_adr_o, wb_dat_o, wb_dat_i, wb_sel_o, wb_cyc_o, wb_stb_o,
-- 	wb_we_o, wb_ack_i, wb_err_i.
-- Not implemented Wishbone signals: clk, rst, rty, req, gnt, lock, stall, tag signals.
 
-- The signals wb_rst and wb_clk are not generated as this is actually the job of the Syscon
-- module and should be done outside this core. Still, it could come in handy to use the core
-- also as Syscon, so these two ports and their processes are only commented out and can be
-- quickly reactivated if necessary.
 
-- Attention! The core was intended for a Wishbone bus scenario where it is the only master.
-- Thus, no arbitration methods are supported, which actually is not 100% WB compatible. Do not
-- put another master on the same WB bus as this core! The advantage is fewer logic units and
-- faster bus cycles (because the core asserts wb_cyc and wb_stb at the same time and doesn't
-- have to wait for a grant in between).
 
-- Supported commands are single read / write. Pipelined mode is not supported.
 
-- All bits of the signal wb_sel are always driven high during normal operation because all WB
-- accesses use 4 Bytes. Only when reset is asserted, wb_sel = 0000.
 
 
-- ########## Device Compatibility ##########
 
-- The core was tested and used on a Xilinx Spartan3 XC3S1000 FT256-4. The PCI master was a
-- MPC5200 microcontroller.
 
-- There are no Xilinx-specific components defined in the code, so theoretically it should be
-- compatible to FPGAs of all developers.
 
-- Utilization (extract from Xilinx ISE Map Report): Slices 183; Slice Reg 143; LUTs 194.
 
-- The IEEE library numeric_std is used.
 
 
-- ########## Change log ##########
 
-- Merged PCI state machine, WB state machine and Address decoder into a single big process to
-- 	allow faster PCI reaction and reduce amount of signals.
-- Made the interrupt asynchronously to clk to ensure fastest possible interrupt generation.
-- In Config cycles, it is now paid attention to the Byte Enable bits cbe.
-- Target-Abort is generated when no response (ack or err) has come from the Wishbone for
-- 	WB_MAX_LAT clock cycles.
-- Completely modified the internal structure of the config signals.
-- Made the interrupt port information configurable via generic.
-- Removed everything that's got to do with interrupts, as an INTA pin is not mandatory for PCI
-- 	and WB has no definition of an interrupt request protocol.
-- Realized main_state signal (formerly pci_state) as an enum type and let it also control all
-- 	the sub states (deleted former sub_state).
 
 
-- ########## ToDos / Problems ##########
 
-- Implement parity check?
-- Implement WB byte select?
-- Check WB Timeout counter accuracy! Don't know whether the cycle count is perfectly correct.
-- Assertion of trdy and stop lasts for about 10 clock cycles when scoped in reality! Reason
-- 	unclear, maybe an effect due to the slow pullups?
-- Uncorrect handling of wb_err assertion (it seems)! Stop isn't asserted sometimes.
--+-----------------------------------------------------------------------------------------------+
 
library ieee;
use ieee.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
 
 
entity pci_to_wb is
	port(
			--PCI signals
		reset			: in  std_logic;
		clk			: in  std_logic;
		frame			: in  std_logic;
		irdy			: in  std_logic;
		trdy			: out std_logic;
		devsel		: out std_logic;
		idsel			: in  std_logic;
		ad				: inout std_logic_vector(31 downto 0) := (others => 'Z');
		cbe			: in  std_logic_vector(3 downto 0);
		par			: inout std_logic := 'Z';
		stop			: out std_logic;
		serr			: out std_logic;
		perr			: out std_logic;
			--Wishbone signals
		-- wb_clk_o		: out std_logic;				--uncomment these two signals and their corresponding processes at the
		-- wb_rst_o		: out std_logic;				--beginning of the architecture body to achieve syscon functionality
		wb_adr_o		: out std_logic_vector(31 downto 0);
		wb_dat_o		: out std_logic_vector(31 downto 0);
		wb_dat_i		: in  std_logic_vector(31 downto 0);
		wb_sel_o		: out std_logic_vector(3 downto 0) := "0000";
		wb_cyc_o		: out std_logic := '0';
		wb_stb_o		: out std_logic := '0';
		wb_we_o		: out std_logic := '0';
		wb_ack_i		: in  std_logic;
		wb_err_i		: in  std_logic
	);
end pci_to_wb;
 
 
architecture Behavioral of pci_to_wb is
 
	--+------------------------------------------------------------------------------------+
	--|												Constants													|
	--+------------------------------------------------------------------------------------+
 
		--user specific constants. Change them at your will.
	constant DEVICE_ID				: std_logic_vector := x"1337";	--It's leet. Yo.
	constant VENDOR_ID				: std_logic_vector := x"1234";
	constant DEVICE_CLASS			: std_logic_vector := x"118000";	--(068000=bridge/other, 078000=simple_comm_contr/other, 118000=data_acquisition/other)
	constant DEVICE_REV				: std_logic_vector := x"09";		--version of the PCI to WB module
	constant SUBSYSTEM_ID			: std_logic_vector := x"0001";	--card identifier
	constant SUBSYSTEM_VENDOR_ID	: std_logic_vector := x"9876";
	constant WB_MAX_LAT				: unsigned := x"4";					--defines how many clock cycles the WB has time to answer to wb_stb before Target-Abort is activated
 
		-- supported PCI commands
	constant CFGREAD					: std_logic_vector := "1010";
	constant CFGWRITE					: std_logic_vector := "1011";
	constant MEMREAD					: std_logic_vector := "0110";
	constant MEMWRITE					: std_logic_vector := "0111";
 
 
	--+------------------------------------------------------------------------------------+
	--|										Internal signals													|
	--+------------------------------------------------------------------------------------+
 
		-- state machine flow
	type main_state_type is (Idle, Cfg_read_1, Cfg_read_2, Cfg_write_1, Cfg_write_2,
									Mem_read_1, Mem_read_2, Mem_read_3, Mem_write_1, Mem_write_2, Mem_write_3);
	signal main_state		: main_state_type := Idle;
	signal wait_count		: unsigned(3 downto 0) := x"0";						--counts up to WB_MAX_LAT while waiting on WB response
	signal par_create		: std_logic := '0';										--controls the parity generator: when 1, parity is generated, else not
 
	signal pci_address	: std_logic_vector(23 downto 2);						--latch of AD lines during the address phase (upper 8 and lower 2 of the 32 bits are never used)
 
		-- configuration registers
	signal cfg_reg_0x00	: std_logic_vector(31 downto 0) := DEVICE_ID & VENDOR_ID;
 
	signal cfg_reg_0x04	: std_logic_vector(31 downto 0) := x"00000000";
	alias target_abort	: std_logic is cfg_reg_0x04(27);						--Target-Abort status bit (status register)
	alias mem_ena			: std_logic is cfg_reg_0x04(1);						--memory space enable bit (command register)
 
	signal cfg_reg_0x08	: std_logic_vector(31 downto 0) := DEVICE_CLASS & DEVICE_REV;
 
	signal cfg_reg_0x10	: std_logic_vector(31 downto 0) := x"00000000";
	alias baseaddr			: std_logic_vector(7 downto 0) is cfg_reg_0x10(31 downto 24);	--used for relocating the WB address space
 
	signal cfg_reg_0x2c	: std_logic_vector(31 downto 0) := SUBSYSTEM_ID & SUBSYSTEM_VENDOR_ID;
 
 
begin
 
	--+------------------------------------------------------------------------------------+
	--|									Small signal processes												|
	--+------------------------------------------------------------------------------------+
		--Wishbone clock and (asynchronous) reset:
	-- wb_clk_o		<= clk;								--uncomment these two processes and their corresponding
	-- wb_rst_o		<= not reset;						--signals in the entity to achieve syscon functionality
 
		--these are not used:
	serr				<= 'Z';
	perr				<= 'Z';
 
		--only dword accesses, so wb_sel can always be high (except during reset):
	process(reset)
	begin
		if reset = '0' then
			wb_sel_o			<= "0000";
		else
			wb_sel_o			<= "1111";
		end if;
	end process;
 
 
	--+------------------------------------------------------------------------------------+
	--|										MAIN STATE MACHINE												|
	--+------------------------------------------------------------------------------------+
	-- This process controls the translation from PCI protocol to Wishbone protocol.
	-- It is realized as a state machine with five main states (defined with main_state).
	-- Most main states are further divided into sub states (defined with sub_state)
	-- to control the flow of execution during a PCI cycle.
	process(reset, clk)
	begin
		if reset = '0' then
			main_state	<= Idle;
 
			ad				<= (others => 'Z');
			devsel		<= 'Z';
			trdy			<= 'Z';
			stop			<= 'Z';
			par_create	<= '0';
			wait_count	<= (others => '0');
 
			target_abort<= '0';
			mem_ena		<= '0';
			baseaddr		<= (others => '0');
 
			wb_adr_o		<= (others => '0');
			wb_dat_o		<= (others => '0');
			wb_cyc_o		<= '0';
			wb_stb_o		<= '0';
			wb_we_o		<= '0';
		elsif rising_edge(clk) then
			case main_state is
 
		-- ########## IDLE STATE ##########
		-- State for between PCI cycles and during the address phase (which is identified by the
		-- assertion of frame). While here, all signals to PCI, WB and internals are in deasserted
		-- state. When the core is being addressed correctly by the PCI master, it asserts devsel
		-- as response and changes to the state defined by the command bits (cbe).
				when Idle =>
					trdy				<= 'Z';
					stop				<= 'Z';
					devsel			<= 'Z';
 
					if frame = '0' then
						pci_address		<= ad(23 downto 2);
						if idsel = '1' and ad(10 downto 8) = "000" and ad(1 downto 0) = "00" then	--correct config space access
							if cbe = CFGREAD then
								devsel		<= '0';
								main_state	<= Cfg_read_1;
							elsif cbe = CFGWRITE then
								devsel		<= '0';
								main_state	<= Cfg_write_1;
							end if;
						elsif mem_ena = '1' and ad(31 downto 24) = baseaddr then							--correct memory space access
							if cbe = MEMREAD then
								devsel		<= '0';
								main_state	<= Mem_read_1;
							elsif cbe = MEMWRITE then
								devsel		<= '0';
								main_state	<= Mem_write_1;
							end if;
						end if;
					end if;
 
 
		-- ########## CFG READ STATE ##########
		-- The config register at the DWord address pci_address is read. Depending on the Byte Enables
		-- cbe, the data is provided on ad When cbe(0) = 0, then byte 0 is all zeroes, etc. One
		-- clock cycle later, the parity is provided and the PCI cycle is terminated.
 
				--STAGE 1: gather register data internally in the first clock cycle where irdy is asserted
				when Cfg_read_1 =>
					if irdy = '0' then
						case pci_address(7 downto 2) is
							when "000000" =>									--0d*4 = 00h. Device ID (31 - 16), Vendor ID (15 - 0).
								if cbe(3) = '0' then
									ad(31 downto 24)	<= cfg_reg_0x00(31 downto 24);
								else
									ad(31 downto 24)	<= (others => '0');
								end if;
								if cbe(2) = '0' then
									ad(23 downto 16)	<= cfg_reg_0x00(23 downto 16);
								else
									ad(23 downto 16)	<= (others => '0');
								end if;
								if cbe(1) = '0' then
									ad(15 downto 8)	<= cfg_reg_0x00(15 downto 8);
								else
									ad(15 downto 8)	<= (others => '0');
								end if;
								if cbe(0) = '0' then
									ad(7 downto 0)		<= cfg_reg_0x00(7 downto 0);
								else
									ad(7 downto 0)		<= (others => '0');
								end if;
							when "000001" =>									--1d*4 = 04h. Status (31 - 16), Command (15 - 0).
								if cbe(3) = '0' then
									ad(31 downto 24)	<= cfg_reg_0x04(31 downto 24);
								else
									ad(31 downto 24)	<= (others => '0');
								end if;
								ad(23 downto 8)		<= (others => '0');
								if cbe(0) = '0' then
									ad(7 downto 0)		<= cfg_reg_0x04(7 downto 0);
								else
									ad(7 downto 0)		<= (others => '0');
								end if;
							when "000010" =>									--2d*4 = 08h. Class Code (31 - 8), Revision ID (7 - 0).
								if cbe(3) = '0' then
									ad(31 downto 24)	<= cfg_reg_0x08(31 downto 24);
								else
									ad(31 downto 24)	<= (others => '0');
								end if;
								if cbe(2) = '0' then
									ad(23 downto 16)	<= cfg_reg_0x08(23 downto 16);
								else
									ad(23 downto 16)	<= (others => '0');
								end if;
								if cbe(1) = '0' then
									ad(15 downto 8)	<= cfg_reg_0x08(15 downto 8);
								else
									ad(15 downto 8)	<= (others => '0');
								end if;
								if cbe(0) = '0' then
									ad(7 downto 0)		<= cfg_reg_0x08(7 downto 0);
								else
									ad(7 downto 0)		<= (others => '0');
								end if;
							when "000100" =>									--4d*4 = 10h. Base Address Register 0, = baseaddr.
								if cbe(3) = '0' then
									ad(31 downto 24)	<= cfg_reg_0x10(31 downto 24);
								else
									ad(31 downto 24)	<= (others => '0');
								end if;
								ad(23 downto 0)		<= (others => '0');
							when "001011" =>									--11d*4 = 2Ch. Subsystem ID (31 - 16), Subsystem Vendor ID (15 - 0).
								if cbe(3) = '0' then
									ad(31 downto 24)	<= cfg_reg_0x2c(31 downto 24);
								else
									ad(31 downto 24)	<= (others => '0');
								end if;
								if cbe(2) = '0' then
									ad(23 downto 16)	<= cfg_reg_0x2c(23 downto 16);
								else
									ad(23 downto 16)	<= (others => '0');
								end if;
								if cbe(1) = '0' then
									ad(15 downto 8)	<= cfg_reg_0x2c(15 downto 8);
								else
									ad(15 downto 8)	<= (others => '0');
								end if;
								if cbe(0) = '0' then
									ad(7 downto 0)		<= cfg_reg_0x2c(7 downto 0);
								else
									ad(7 downto 0)		<= (others => '0');
								end if;
							when others =>					--unsupported or reserved config registers.
								ad							<= (others => '0');
						end case;
 
						trdy			<= '0';
						stop			<= '0';
						par_create	<= '1';
						main_state	<= Cfg_read_2;
					end if;
 
				--STAGE 2: one clock cycle later, end the PCI cycle
				when Cfg_read_2 =>
					ad				<= (others => 'Z');
					devsel		<= '1';
					trdy			<= '1';
					stop			<= '1';
					par_create	<= '0';
					main_state	<= Idle;
 
 
		-- ########## CFG WRITE STATE ##########
		-- The config register at the DWord address pci_address is written, depending on the Byte Enables
		-- cbe. Some bits are not writable, so nothing will be changed then. The status register
		-- is special: When writing a 1 onto a bit, this bit is cleared; writing a 0 will have no
		-- effect. One clock cycle later, the PCI cycle is terminated.
 
				-- STAGE 1: return config values in the first clock cycle where irdy is asserted
				when Cfg_write_1 =>
					trdy				<= '0';
					stop				<= '0';
					if irdy = '0' then
						case pci_address(7 downto 2) is
							when "000001" =>									--1d*4 = 04h. Status (31 - 16), Command (15 - 0).
								if cbe(3) = '0' and ad(27) = '1' then
									target_abort<= '0';						--reset status bit Target-Abort when writing a 1 there
								end if;
								if cbe(0) = '0' then
									mem_ena		<= ad(1);
								end if;
							when "000100" =>									--4d*4 = 10h. Base Address Register 0 (BAR0).
								if cbe(3) = '0' then
									baseaddr		<= ad(31 downto 24);
								end if;
							when others =>										--config registers that are reserved, unsupported or don't support writes.
								null;
						end case;
						main_state	<= Cfg_write_2;
					end if;
 
				--STAGE 2: one clock cycle later, end the PCI cycle
				when Cfg_write_2 =>
					devsel		<= '1';
					trdy			<= '1';
					stop			<= '1';
					main_state	<= Idle;
 
 
		-- ########## MEM READ STATE ##########
		-- The data to be written and the address is provided for the Wishbone bus. Then,
		-- wait for Wishbone response:
		-- When ack_i is asserted (= data ready), signal "Disconnect with data" to PCI master,
		-- 	provide the data and one clock cycle later the parity.
		-- When err_i is asserted (= access error), signal "Target-Abort". In this case, no
		-- 	data is provided and the third stage is not activated.
		-- When neither ack_i nor err_i were asserted for WB_MAX_LAT clock cycles, signal
		-- 	"Target-Abort". The third stage is not activated then, too.
 
				--STAGE 1: save address for Wishbone in the first clock cycle where irdy is asserted and initiate WB action
				when Mem_read_1 =>
					if irdy = '0' then
						wb_adr_o		<= "0000000000" & pci_address;
						wb_cyc_o		<= '1';							--set the Wishbone master signals for a read cycle
						wb_stb_o		<= '1';
						wait_count	<= x"0";							--reset timeout counter
						main_state	<= Mem_read_2;
					end if;
 
				--STAGE 2: wait for Wishbone response, react accordingly to the PCI bus and end the WB cycle
				when Mem_read_2 =>
					if wb_ack_i = '1' then							--WB transaction completed
						wb_adr_o			<= (others => '0');
						wb_cyc_o			<= '0';
						wb_stb_o			<= '0';
						ad					<= wb_dat_i;
						trdy				<= '0';						--trdy and stop asserted at the same time -> Disconnect
						stop				<= '0';
						par_create		<= '1';
						main_state		<= Mem_read_3;
					elsif wb_err_i = '1' or wait_count = WB_MAX_LAT then	--WB transaction aborted, or no WB answer for WB_MAX_LAT clock cycles
						wb_adr_o			<= (others => '0');
						wb_cyc_o			<= '0';
						wb_stb_o			<= '0';
						devsel			<= '1';						--stop asserted and devsel deasserted at the same time -> Target-Abort
						stop				<= '0';
						target_abort	<= '1';						--status register entry
						main_state		<= Idle;
					end if;
					wait_count		<= wait_count + 1;			--count the wait cycles
 
				--STAGE 3: one clock cycle later, end the PCI cycle (only after Disconnect)
				when Mem_read_3 =>
					ad					<= (others => 'Z');
					devsel			<= '1';
					trdy				<= '1';
					stop				<= '1';
					par_create		<= '0';
					main_state		<= Idle;
 
 
		-- ########## MEM WRITE STATE ##########
		-- The data to be written and the address is provided for the Wishbone bus. Then,
		-- wait for Wishbone response:
		-- When ack_i is asserted (= data was stored), signal "Disconnect with data" to PCI
		-- 	master and end the PCI cycle on the next clock edge.
		-- When err_i is asserted (= access error, no transaction), signal "Target-Abort". In
		-- 	this case, no data was changed and the third stage is not activated.
		-- When neither ack_i nor err_i were asserted for WB_MAX_LAT clock cycles, signal
		-- 	"Target-Abort". The third stage is not activated then, too.
 
				--STAGE 1: save write data for WB in the first clock cycle where irdy is asserted and initiate WB action
				when Mem_write_1 =>
					if irdy = '0' then
						wb_adr_o		<= x"00" & "00" & pci_address;
						wb_dat_o		<= ad;
						wb_cyc_o		<= '1';							--set the Wishbone master signals for a write cycle
						wb_stb_o		<= '1';
						wb_we_o		<= '1';
						wait_count	<= x"0";							--reset timeout counter
						main_state	<= Mem_write_2;
					end if;
 
				--STAGE 2: wait for Wishbone response, react accordingly to the PCI bus and end the WB cycle
				when Mem_write_2 =>
					if wb_ack_i = '1' then							--WB transaction completed
						wb_adr_o		<= (others => '0');
						wb_dat_o		<= (others => '0');
						wb_cyc_o		<= '0';
						wb_stb_o		<= '0';
						wb_we_o		<= '0';
						trdy			<= '0';							--trdy and stop asserted at the same time -> Disconnect
						stop			<= '0';
						main_state	<= Mem_write_3;
					elsif wb_err_i = '1' or wait_count = WB_MAX_LAT then	--WB transaction aborted, or no WB answer for WB_MAX_LAT clock cycles
						wb_adr_o		<= (others => '0');
						wb_dat_o		<= (others => '0');
						wb_cyc_o		<= '0';
						wb_stb_o		<= '0';
						wb_we_o		<= '0';
						devsel		<= '1';							--stop asserted and devsel deasserted at the same time -> Target-Abort
						stop			<= '0';
						target_abort<= '1';							--status register entry
						main_state	<= Idle;
					end if;
					wait_count		<= wait_count + 1;			--count the wait cycles
 
				--STAGE 3: one clock cycle later, end the PCI cycle (only after Disconnect)
				when Mem_write_3 =>
					devsel			<= '1';
					trdy				<= '1';
					stop				<= '1';
					main_state		<= Idle;
 
 
		-- ########## undefined state ##########
		-- This state normally should never occur. Just for completion.
				when others =>
					main_state			<= Idle;
 
			end case;
		end if;
	end process;
 
 
	--+------------------------------------------------------------------------------------+
	--|										Parity generation													|
	--+------------------------------------------------------------------------------------+
	-- This process calcutates the even parity of the ad and cbe lines when par_create is
	-- asserted. The main state machine asserts par_create exactly when trdy is asserted
	-- in a Read cycle (both Config and Memory). Because this process sees the assertion
	-- of par_create only on the following clock edge, parity for the master is always
	-- provided one clock cycle delayed to ad (which is required by PCI).
	process(reset, clk)
	begin
		if reset = '0' then
			par		<= 'Z';
		elsif rising_edge(clk) then
			if par_create = '1' then
				par	<=	( ad(31) xor ad(30) xor ad(29) xor ad(28) ) xor
							( ad(27) xor ad(26) xor ad(25) xor ad(24) ) xor
							( ad(23) xor ad(22) xor ad(21) xor ad(20) ) xor
							( ad(19) xor ad(18) xor ad(17) xor ad(16) ) xor
							( ad(15) xor ad(14) xor ad(13) xor ad(12) ) xor
							( ad(11) xor ad(10) xor ad(9)  xor ad(8)  ) xor
							( ad(7)  xor ad(6)  xor ad(5)  xor ad(4)  ) xor
							( ad(3)  xor ad(2)  xor ad(1)  xor ad(0)  ) xor
							( cbe(3) xor cbe(2) xor cbe(1) xor cbe(0) );
			else
				par	<= 'Z';
			end if;
		end if;
	end process;
 
 
end Behavioral;

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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