URL
https://opencores.org/ocsvn/pci/pci/trunk
Subversion Repositories pci
Compare Revisions
- This comparison shows the changes necessary to convert path
/pci/tags/rel_10/rtl
- from Rev 125 to Rev 154
- ↔ Reverse comparison
Rev 125 → Rev 154
/verilog/pci_wb_master.v
0,0 → 1,1167
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: wb_master.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2003/08/21 20:56:40 tadejm |
// WB Master is now WISHBONE B3 compatible. |
// |
// Revision 1.3 2003/03/14 15:31:57 mihad |
// Entered the option to disable no response counter in wb master. |
// |
// Revision 1.2 2003/01/30 22:01:09 mihad |
// Updated synchronization in top level fifo modules. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.7 2002/12/05 12:19:23 mihad |
// *** empty log message *** |
// |
// Revision 1.6 2002/10/11 14:15:29 mihad |
// Cleaned up non-blocking assignments in combinatinal logic statements |
// |
// Revision 1.5 2002/03/05 11:53:47 mihad |
// Added some testcases, removed un-needed fifo signals |
// |
// Revision 1.4 2002/02/19 16:32:37 mihad |
// Modified testbench and fixed some bugs |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`define WB_FSM_BITS 3 // number of bits needed for FSM states |
|
|
`include "bus_commands.v" |
`include "pci_constants.v" |
//synopsys translate_off |
`include "timescale.v" |
//synopsys translate_on |
|
module pci_wb_master |
( wb_clock_in, // CLK_I |
reset_in, // RST_I |
|
pci_tar_read_request, |
pci_tar_address, |
pci_tar_cmd, |
pci_tar_be, |
pci_tar_burst_ok, |
pci_cache_line_size, |
cache_lsize_not_zero, |
wb_read_done_out, |
w_attempt, |
|
pcir_fifo_wenable_out, |
pcir_fifo_data_out, |
pcir_fifo_be_out, |
pcir_fifo_control_out, |
//pcir_fifo_renable_out, for PCI Target !!! |
//pcir_fifo_data_in, for PCI Target !!! |
//pcir_fifo_be_in, for PCI Target !!! |
//pcir_fifo_control_in, for PCI Target !!! |
//pcir_fifo_flush_out, for PCI Target !!! |
//pcir_fifo_almost_empty_in, for PCI Target !!! |
//pcir_fifo_empty_in, NOT used |
//pcir_fifo_transaction_ready_in, NOT used |
//pciw_fifo_wenable_out, for PCI Target !!! |
//pciw_fifo_addr_data_out, for PCI Target !!! |
//pciw_fifo_cbe_out, for PCI Target !!! |
//pciw_fifo_control_out, for PCI Target !!! |
pciw_fifo_renable_out, |
pciw_fifo_addr_data_in, |
pciw_fifo_cbe_in, |
pciw_fifo_control_in, |
//pciw_fifo_flush_out, NOT used |
//pciw_fifo_almost_full_in, for PCI Target !!! |
//pciw_fifo_full_in, for PCI Target !!! |
pciw_fifo_almost_empty_in, |
pciw_fifo_empty_in, |
pciw_fifo_transaction_ready_in, |
|
pci_error_sig_out, |
pci_error_bc, |
write_rty_cnt_exp_out, |
error_source_out, |
read_rty_cnt_exp_out, |
|
wb_cyc_o, |
wb_stb_o, |
wb_we_o, |
wb_cti_o, |
wb_bte_o, |
wb_sel_o, |
wb_adr_o, |
wb_dat_i, |
wb_dat_o, |
wb_ack_i, |
wb_rty_i, |
wb_err_i |
// CYC_O, |
// STB_O, |
// WE_O, |
// SEL_O, |
// ADR_O, |
// MDATA_I, |
// MDATA_O, |
// ACK_I, |
// RTY_I, |
// ERR_I, |
); |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Various parameters needed for state machine and other stuff |
----------------------------------------------------------------------------------------------------------------------*/ |
parameter S_IDLE = `WB_FSM_BITS'h0 ; |
parameter S_WRITE = `WB_FSM_BITS'h1 ; |
parameter S_WRITE_ERR_RTY = `WB_FSM_BITS'h2 ; |
parameter S_READ = `WB_FSM_BITS'h3 ; |
parameter S_READ_RTY = `WB_FSM_BITS'h4 ; |
parameter S_TURN_ARROUND = `WB_FSM_BITS'h5 ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
System signals inputs |
wb_clock_in - WISHBONE bus clock input |
reset_in - system reset input controlled by bridge's reset logic |
----------------------------------------------------------------------------------------------------------------------*/ |
input wb_clock_in ; |
input reset_in ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Control signals from PCI Target for READS to PCIR_FIFO |
---------------------------------------------------------------------------------------------------------------------*/ |
input pci_tar_read_request ; // read request from PCI Target |
input [31:0] pci_tar_address ; // address for requested read from PCI Target |
input [3:0] pci_tar_cmd ; // command for requested read from PCI Target |
input [3:0] pci_tar_be ; // byte enables for requested read from PCI Target |
input pci_tar_burst_ok ; |
input [7:0] pci_cache_line_size ; // CACHE line size register value for burst length |
input cache_lsize_not_zero ; |
output wb_read_done_out ; // read done and PCIR_FIFO has data ready |
output w_attempt ; |
|
reg wb_read_done_out ; |
reg wb_read_done ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
PCIR_FIFO control signals used for sinking data into PCIR_FIFO and status monitoring |
---------------------------------------------------------------------------------------------------------------------*/ |
output pcir_fifo_wenable_out ; // PCIR_FIFO write enable output |
output [31:0] pcir_fifo_data_out ; // data output to PCIR_FIFO |
output [3:0] pcir_fifo_be_out ; // byte enable output to PCIR_FIFO |
output [3:0] pcir_fifo_control_out ; // control bus output to PCIR_FIFO |
|
reg [31:0] pcir_fifo_data_out ; |
reg pcir_fifo_wenable_out ; |
reg pcir_fifo_wenable ; |
reg [3:0] pcir_fifo_control_out ; |
reg [3:0] pcir_fifo_control ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
PCIW_FIFO control signals used for fetching data from PCIW_FIFO and status monitoring |
---------------------------------------------------------------------------------------------------------------------*/ |
output pciw_fifo_renable_out ; // read enable for PCIW_FIFO output |
input [31:0] pciw_fifo_addr_data_in ; // address and data input from PCIW_FIFO |
input [3:0] pciw_fifo_cbe_in ; // command and byte_enables from PCIW_FIFO |
input [3:0] pciw_fifo_control_in ; // control bus input from PCIW_FIFO |
input pciw_fifo_almost_empty_in ; // almost empty status indicator from PCIW_FIFO |
input pciw_fifo_empty_in ; // empty status indicator from PCIW_FIFO |
input pciw_fifo_transaction_ready_in ; // write transaction is ready in PCIW_FIFO |
|
reg pciw_fifo_renable_out ; |
reg pciw_fifo_renable ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Control INPUT / OUTPUT signals for configuration space reporting registers !!! |
---------------------------------------------------------------------------------------------------------------------*/ |
output pci_error_sig_out ; // When error occures (on WB bus, retry counter, etc.) |
output [3:0] pci_error_bc ; // bus command at which error occured ! |
output write_rty_cnt_exp_out ; // Signaling that RETRY counter has expired during write transaction! |
output read_rty_cnt_exp_out ; // Signaling that RETRY counter has expired during read transaction! |
// if error_source is '0' other side didn't respond |
// if error_source is '1' other side RETRIED for max retry counter value |
output error_source_out ; // Signaling error source - '0' other WB side signaled error OR didn't respond |
// if '1' wridge counted max value in retry counter because of RTY responds |
reg pci_error_sig_out ; |
reg write_rty_cnt_exp_out ; |
reg read_rty_cnt_exp_out ; |
reg error_source_out ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
WISHBONE bus interface signals - can be connected directly to WISHBONE bus |
---------------------------------------------------------------------------------------------------------------------*/ |
output wb_cyc_o; // cycle indicator output |
output wb_stb_o; // strobe output - data is valid when strobe and cycle indicator are high |
output wb_we_o; // write enable output - 1 - write operation, 0 - read operation |
output [2:0] wb_cti_o; // WB B3 - cycle type identifier |
output [1:0] wb_bte_o; // WB B3 - burst type |
output [3:0] wb_sel_o; // Byte select outputs |
output [31:0] wb_adr_o; // WISHBONE address output |
input [31:0] wb_dat_i; // WISHBONE interface input data bus |
output [31:0] wb_dat_o; // WISHBONE interface output data bus |
input wb_ack_i; // Acknowledge input - qualifies valid data on data output bus or received data on data input bus |
input wb_rty_i; // retry input - signals from WISHBONE slave that cycle should be terminated and retried later |
input wb_err_i; // Signals from WISHBONE slave that access resulted in an error |
|
reg wb_cyc_o; |
reg wb_stb_o; |
reg wb_we_o; |
reg [2:0] wb_cti_o; |
reg [1:0] wb_bte_o; |
reg [3:0] wb_sel_o; |
reg [31:0] wb_dat_o; |
|
|
|
/*########################################################################################################### |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
LOGIC, COUNTERS, STATE MACHINE and some control register bits |
============================================================= |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
###########################################################################################################*/ |
|
reg last_data_transferred ; // signal is set by STATE MACHINE after each complete transfere ! |
|
// wire for write attempt - 1 when PCI Target attempt to write and PCIW_FIFO has a write transaction ready |
reg w_attempt; |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) |
w_attempt <= #`FF_DELAY 1'b0; |
else |
begin |
if (pciw_fifo_transaction_ready_in && ~pciw_fifo_empty_in) |
w_attempt <= #`FF_DELAY 1'b1; |
else |
if (last_data_transferred) |
w_attempt <= #`FF_DELAY 1'b0; |
end |
end |
|
// wire for read attempt - 1 when PCI Target is attempting a read and PCIR_FIFO is not full ! |
// because of transaction ordering, PCI Master must not start read untill all writes are done -> at that |
// moment PCIW_FIFO is empty !!! (when read is pending PCI Target will block new reads and writes) |
wire r_attempt = ( pci_tar_read_request && !w_attempt && pciw_fifo_empty_in ) ; |
|
// Signal is used for reads on WB, when there is retry! |
reg first_wb_data_access ; |
|
reg last_data_from_pciw_fifo ; // signal tells when there is last data in pciw_fifo |
reg last_data_from_pciw_fifo_reg ; |
reg last_data_to_pcir_fifo ; // signal tells when there will be last data for pcir_fifo |
|
// Logic used in State Machine logic implemented out of State Machine because of less delay! |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) |
last_data_from_pciw_fifo <= #`FF_DELAY 1'b0 ; |
else |
begin |
if ((pciw_fifo_renable_out) && |
(pciw_fifo_control_in[`LAST_CTRL_BIT] || pciw_fifo_almost_empty_in)) // if last data is going to be transfered |
last_data_from_pciw_fifo <= #`FF_DELAY 1'b1 ; // signal for last data from PCIW_FIFO |
else |
last_data_from_pciw_fifo <= #`FF_DELAY 1'b0 ; |
end |
end |
|
reg read_count_load; |
reg read_count_enable; |
|
reg [(`PCIR_ADDR_LENGTH - 1):0] max_read_count ; |
always@(pci_cache_line_size or cache_lsize_not_zero or pci_tar_cmd) |
begin |
if (cache_lsize_not_zero) |
if ( (pci_cache_line_size >= `PCIR_DEPTH) || (~pci_tar_cmd[1] && ~pci_tar_cmd[0]) ) |
// If cache line size is larger than FIFO or BC_MEM_READ_MUL command is performed! |
max_read_count = `PCIR_DEPTH - 1'b1; |
else |
max_read_count = pci_cache_line_size ; |
else |
max_read_count = 1'b1; |
end |
|
reg [(`PCIR_ADDR_LENGTH - 1):0] read_count ; |
|
// cache line bound indicator - it signals when data for one complete cacheline was read |
wire read_bound_comb = ~|( { read_count[(`PCIR_ADDR_LENGTH - 1):2], read_count[0] } ) ; |
|
reg read_bound ; |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if ( reset_in ) |
read_bound <= #`FF_DELAY 1'b0 ; |
else if (read_count_load) |
read_bound <= #`FF_DELAY 1'b0 ; |
else if ( read_count_enable ) |
read_bound <= #`FF_DELAY read_bound_comb ; |
end |
|
// down counter with load |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
read_count <= #`FF_DELAY 0 ; |
else |
if (read_count_load) |
read_count <= #`FF_DELAY max_read_count ; |
else |
if (read_count_enable) |
read_count <= #`FF_DELAY read_count - 1'b1 ; |
end |
|
// Logic used in State Machine logic implemented out of State Machine because of less delay! |
// definition of signal telling, when there is last data written into FIFO |
always@(pci_tar_cmd or pci_tar_burst_ok or read_bound) |
begin |
// burst is OK for reads when there is ((MEM_READ_LN or MEM_READ_MUL) and AD[1:0]==2'b00) OR |
// (MEM_READ and Prefetchable_IMAGE and AD[1:0]==2'b00) -> pci_tar_burst_ok |
case ({pci_tar_cmd, pci_tar_burst_ok}) |
{`BC_MEM_READ, 1'b1}, |
{`BC_MEM_READ_LN, 1'b1} : |
begin // when burst cycle |
if (read_bound) |
last_data_to_pcir_fifo = 1'b1 ; |
else |
last_data_to_pcir_fifo = 1'b0 ; |
end |
{`BC_MEM_READ_MUL, 1'b1} : |
begin // when burst cycle |
if (read_bound) |
last_data_to_pcir_fifo = 1'b1 ; |
else |
last_data_to_pcir_fifo = 1'b0 ; |
end |
default : |
// {`BC_IO_READ, 1'b0}, |
// {`BC_IO_READ, 1'b1}, |
// {`BC_MEM_READ, 1'b0}, |
// {`BC_MEM_READ_LN, 1'b0}, |
// {`BC_MEM_READ_MUL, 1'b0}: |
begin // when single cycle |
last_data_to_pcir_fifo = 1'b1 ; |
end |
endcase |
end |
|
reg wait_for_wb_response ; |
|
`ifdef PCI_WBM_NO_RESPONSE_CNT_DISABLE |
wire set_retry = 1'b0 ; |
|
`else |
reg [3:0] wb_no_response_cnt ; |
reg [3:0] wb_response_value ; |
reg set_retry ; // |
|
// internal WB no response retry generator counter! |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
wb_no_response_cnt <= #`FF_DELAY 4'h0 ; |
else |
wb_no_response_cnt <= #`FF_DELAY wb_response_value ; |
end |
// internal WB no response retry generator logic |
always@(wait_for_wb_response or wb_no_response_cnt) |
begin |
if (wb_no_response_cnt == 4'h8) // when there isn't response for 8 clocks, set internal retry |
begin |
wb_response_value = 4'h0 ; |
set_retry = 1'b1 ; |
end |
else |
begin |
if (wait_for_wb_response) |
wb_response_value = wb_no_response_cnt + 1'h1 ; // count clocks when no response |
else |
wb_response_value = 4'h0 ; |
set_retry = 1'b0 ; |
end |
end |
`endif |
|
wire retry = wb_rty_i || set_retry ; // retry signal - logic OR function between wb_rty_i and internal WB no response retry! |
reg [7:0] rty_counter ; // output from retry counter |
reg [7:0] rty_counter_in ; // input value - output value + 1 OR output value |
reg rty_counter_almost_max_value ; // signal tells when retry counter riches maximum value - 1! |
reg reset_rty_cnt ; // signal for asynchronous reset of retry counter after each complete transfere |
|
// sinchronous signal after each transfere and asynchronous signal 'reset_rty_cnt' after reset |
// for reseting the retry counter |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
reset_rty_cnt <= #`FF_DELAY 1'b1 ; // asynchronous set when reset signal is active |
else |
reset_rty_cnt <= #`FF_DELAY wb_ack_i || wb_err_i || last_data_transferred ; // synchronous set after completed transfere |
end |
|
// Retry counter register control |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
rty_counter <= #`FF_DELAY 8'h00 ; |
else |
begin |
if (reset_rty_cnt) |
rty_counter <= #`FF_DELAY 8'h00 ; |
else if (retry) |
rty_counter <= #`FF_DELAY rty_counter_in ; |
end |
end |
// Retry counter logic |
always@(rty_counter) |
begin |
if(rty_counter == `WB_RTY_CNT_MAX - 1'b1) // stop counting |
begin |
rty_counter_in = rty_counter ; |
rty_counter_almost_max_value = 1'b1 ; |
end |
else |
begin |
rty_counter_in = rty_counter + 1'b1 ; // count up |
rty_counter_almost_max_value = 1'b0 ; |
end |
end |
|
reg [31:0] addr_cnt_out ; // output value from address counter to WB ADDRESS output |
reg [31:0] addr_cnt_in ; // input address value to address counter |
reg addr_into_cnt ; // control signal for loading starting address into counter |
reg addr_into_cnt_reg ; |
reg addr_count ; // control signal for count enable |
reg [3:0] bc_register ; // used when error occures during writes! |
|
// wb address counter register control |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) // reset counter |
begin |
addr_cnt_out <= #`FF_DELAY 32'h0000_0000 ; |
bc_register <= #`FF_DELAY 4'h0 ; |
addr_into_cnt_reg <= #`FF_DELAY 1'b0; |
end |
else |
begin |
addr_cnt_out <= #`FF_DELAY addr_cnt_in ; // count up or hold value depending on cache line counter logic |
addr_into_cnt_reg <= #`FF_DELAY addr_into_cnt; |
if (addr_into_cnt) |
bc_register <= #`FF_DELAY pciw_fifo_cbe_in ; |
end |
end |
|
// when '1', the bus command is IO command - not supported commands are checked in pci_decoder modules |
wire io_memory_bus_command = !pci_tar_cmd[3] && !pci_tar_cmd[2] ; |
|
// wb address counter logic |
always@(addr_into_cnt or r_attempt or addr_count or pciw_fifo_addr_data_in or pci_tar_address or addr_cnt_out or |
io_memory_bus_command) |
begin |
if (addr_into_cnt) // load starting address into counter |
begin |
if (r_attempt) |
begin // if read request, then load read addresss from PCI Target |
addr_cnt_in = {pci_tar_address[31:2], pci_tar_address[1] && io_memory_bus_command, |
pci_tar_address[0] && io_memory_bus_command} ; |
end |
else |
begin // if not read request, then load write address from PCIW_FIFO |
addr_cnt_in = pciw_fifo_addr_data_in[31:0] ; |
end |
end |
else |
if (addr_count) |
begin |
addr_cnt_in = addr_cnt_out + 3'h4 ; // count up for 32-bit alligned address |
end |
else |
begin |
addr_cnt_in = addr_cnt_out ; |
end |
end |
|
reg retried ; // Signal is output value from FF and is set for one clock period after retried_d is set |
reg retried_d ; // Signal is set whenever cycle is retried and is input to FF for delaying -> used in S_IDLE state |
reg retried_write; |
reg rty_i_delayed; // Dignal used for determinig the source of retry! |
|
reg first_data_is_burst ; // Signal is set in S_WRITE or S_READ states, when data transfere is burst! |
reg first_data_is_burst_reg ; |
wire burst_transfer ; // This signal is set when data transfere is burst and is reset with RESET or last data transfered |
reg burst_chopped; // This signal is set when WB_SEL_O is changed during burst write transaction |
reg burst_chopped_delayed; |
|
// FFs output signals tell, when there is first data out from FIFO (for BURST checking) |
// and for delaying retried signal |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) // reset signals |
begin |
retried <= #`FF_DELAY 1'b0 ; |
retried_write <= #`FF_DELAY 1'b0 ; |
rty_i_delayed <= #`FF_DELAY 1'B0 ; |
end |
else |
begin |
retried <= #`FF_DELAY retried_d ; // delaying retried signal |
retried_write <= #`FF_DELAY retried ; |
rty_i_delayed <= #`FF_DELAY wb_rty_i ; |
end |
end |
|
// Determinig if first data is a part of BURST or just a single transfere! |
always@(addr_into_cnt or r_attempt or pci_tar_burst_ok or max_read_count or |
pciw_fifo_control_in or pciw_fifo_empty_in) |
begin |
if (addr_into_cnt) |
begin |
if (r_attempt) |
begin |
// burst is OK for reads when there is ((MEM_READ_LN or MEM_READ_MUL) and AD[1:0]==2'b00) OR |
// (MEM_READ and Prefetchable_IMAGE and AD[1:0]==2'b00) -> pci_tar_burst_ok |
if (pci_tar_burst_ok && (max_read_count != 8'h1)) |
first_data_is_burst = 1'b1 ; |
else |
first_data_is_burst = 1'b0 ; |
end |
else |
begin |
first_data_is_burst = 1'b0 ; |
end |
end |
else |
first_data_is_burst = pciw_fifo_control_in[`BURST_BIT] && ~pciw_fifo_empty_in && |
~pciw_fifo_control_in[`LAST_CTRL_BIT] /*&& ~pciw_fifo_control_in[`DATA_ERROR_CTRL_BIT]*/; |
end |
|
// FF for seting and reseting burst_transfer signal |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
burst_chopped <= #`FF_DELAY 1'b0; |
burst_chopped_delayed <= #`FF_DELAY 1'b0; |
first_data_is_burst_reg <= #`FF_DELAY 1'b0 ; |
end |
else |
begin |
if (pciw_fifo_transaction_ready_in) |
begin |
if (pciw_fifo_control_in[`DATA_ERROR_CTRL_BIT]) |
burst_chopped <= #`FF_DELAY 1'b1; |
else if (wb_ack_i || wb_err_i || wb_rty_i) |
burst_chopped <= #`FF_DELAY 1'b0; |
end |
else |
burst_chopped <= #`FF_DELAY 1'b0; |
burst_chopped_delayed <= #`FF_DELAY burst_chopped; |
if (last_data_transferred || first_data_is_burst) |
first_data_is_burst_reg <= #`FF_DELAY ~last_data_transferred ; |
end |
end |
assign burst_transfer = first_data_is_burst || first_data_is_burst_reg ; |
|
reg [(`WB_FSM_BITS - 1):0] c_state ; //current state register |
reg [(`WB_FSM_BITS - 1):0] n_state ; //next state input to current state register |
|
//################################## |
// WISHBONE B3 master state machine |
//################################## |
|
// state machine register control and registered outputs (without wb_adr_o counter) |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) // reset state machine to S_IDLE state |
begin |
c_state <= #`FF_DELAY S_IDLE; |
wb_cyc_o <= #`FF_DELAY 1'b0; |
wb_stb_o <= #`FF_DELAY 1'b0; |
wb_we_o <= #`FF_DELAY 1'b0; |
wb_cti_o <= #`FF_DELAY 3'h2; |
wb_bte_o <= #`FF_DELAY 2'h0; |
wb_sel_o <= #`FF_DELAY 4'h0; |
wb_dat_o <= #`FF_DELAY 32'h0; |
pcir_fifo_data_out <= #`FF_DELAY 32'h0; |
pcir_fifo_control_out <= #`FF_DELAY 4'h0; |
pcir_fifo_wenable_out <= #`FF_DELAY 1'b0; |
end |
else |
begin |
c_state <= #`FF_DELAY n_state; |
wb_bte_o <= #`FF_DELAY 2'h0; |
case (n_state) // synthesis parallel_case full_case |
S_WRITE: |
begin |
wb_cyc_o <= #`FF_DELAY ~addr_into_cnt; |
wb_stb_o <= #`FF_DELAY ~addr_into_cnt; |
wb_we_o <= #`FF_DELAY ~addr_into_cnt; |
// if '1' then next burst BE is not equat to current one => burst is chopped into singles |
// OR if last data is going to be transfered |
if ((wb_stb_o && wb_ack_i) || addr_into_cnt_reg || (~wb_cyc_o && (retried || burst_chopped_delayed))) |
begin |
if (burst_transfer && ~pciw_fifo_control_in[`DATA_ERROR_CTRL_BIT] && |
~(pciw_fifo_renable_out && (pciw_fifo_control_in[`LAST_CTRL_BIT] || pciw_fifo_almost_empty_in))) |
wb_cti_o <= #`FF_DELAY 3'h2; |
else |
wb_cti_o <= #`FF_DELAY 3'h7; |
end |
if ((pciw_fifo_renable_out && ~addr_into_cnt) || addr_into_cnt_reg) |
begin |
wb_sel_o <= #`FF_DELAY ~pciw_fifo_cbe_in; |
wb_dat_o <= #`FF_DELAY pciw_fifo_addr_data_in; |
end |
end |
S_WRITE_ERR_RTY: |
begin |
wb_cyc_o <= #`FF_DELAY 1'b0; |
wb_stb_o <= #`FF_DELAY 1'b0; |
wb_we_o <= #`FF_DELAY 1'b0; |
wb_cti_o <= #`FF_DELAY 3'h2; |
// stay the same as previous |
//wb_sel_o <= #`FF_DELAY 4'h0; |
//wb_dat_o <= #`FF_DELAY 32'h0; |
end |
S_READ: |
begin |
wb_cyc_o <= #`FF_DELAY ~addr_into_cnt; |
wb_stb_o <= #`FF_DELAY ~addr_into_cnt; |
wb_we_o <= #`FF_DELAY 1'b0; |
if ((wb_stb_o && wb_ack_i) || addr_into_cnt_reg || (~wb_cyc_o && retried)) |
begin |
if (burst_transfer && ~read_bound_comb) |
wb_cti_o <= #`FF_DELAY 3'h2; |
else |
wb_cti_o <= #`FF_DELAY 3'h7; |
end |
if (burst_transfer) |
wb_sel_o <= #`FF_DELAY 4'hF; |
else |
wb_sel_o <= #`FF_DELAY ~pci_tar_be; |
// no need to change att all |
//wb_dat_o <= #`FF_DELAY 32'h0; |
end |
S_READ_RTY: |
begin |
wb_cyc_o <= #`FF_DELAY 1'b0; |
wb_stb_o <= #`FF_DELAY 1'b0; |
wb_we_o <= #`FF_DELAY 1'b0; |
wb_cti_o <= #`FF_DELAY 3'h2; |
// no need to change att all |
//wb_sel_o <= #`FF_DELAY 4'h0; |
//wb_dat_o <= #`FF_DELAY 32'h0; |
end |
S_TURN_ARROUND: |
begin |
wb_cyc_o <= #`FF_DELAY 1'b0; |
wb_stb_o <= #`FF_DELAY 1'b0; |
wb_we_o <= #`FF_DELAY 1'b0; |
wb_cti_o <= #`FF_DELAY 3'h2; |
// no need to change att all |
//wb_sel_o <= #`FF_DELAY 4'h0; |
//wb_dat_o <= #`FF_DELAY 32'h0; |
end |
default: // S_IDLE: |
begin |
wb_cyc_o <= #`FF_DELAY 1'b0; |
wb_stb_o <= #`FF_DELAY 1'b0; |
wb_we_o <= #`FF_DELAY 1'b0; |
wb_cti_o <= #`FF_DELAY 3'h2; |
// no need to change att all |
//wb_sel_o <= #`FF_DELAY 4'h0; |
//wb_dat_o <= #`FF_DELAY 32'h0; |
end |
endcase |
pcir_fifo_data_out <= #`FF_DELAY wb_dat_i; |
pcir_fifo_control_out <= #`FF_DELAY pcir_fifo_control ; |
pcir_fifo_wenable_out <= #`FF_DELAY pcir_fifo_wenable ; |
end |
end |
|
assign wb_adr_o = addr_cnt_out ; |
|
// state machine logic |
always@(c_state or |
wb_ack_i or |
wb_rty_i or |
wb_err_i or |
w_attempt or |
r_attempt or |
retried or |
burst_chopped or |
burst_chopped_delayed or |
rty_i_delayed or |
pci_tar_read_request or |
rty_counter_almost_max_value or |
set_retry or |
last_data_to_pcir_fifo or |
first_wb_data_access or |
pciw_fifo_control_in or |
pciw_fifo_empty_in or |
burst_transfer or |
last_data_from_pciw_fifo_reg |
) |
begin |
case (c_state) |
S_IDLE: |
begin |
// Default values for signals not used in this state |
pcir_fifo_wenable = 1'b0 ; |
pcir_fifo_control = 4'h0 ; |
addr_count = 1'b0 ; |
read_count_enable = 1'b0 ; |
pci_error_sig_out = 1'b0 ; |
error_source_out = 1'b0 ; |
retried_d = 1'b0 ; |
last_data_transferred = 1'b0 ; |
wb_read_done = 1'b0 ; |
wait_for_wb_response = 1'b0 ; |
write_rty_cnt_exp_out = 1'b0 ; |
pci_error_sig_out = 1'b0 ; |
read_rty_cnt_exp_out = 1'b0 ; |
case ({w_attempt, r_attempt, retried}) |
3'b101 : // Write request for PCIW_FIFO to WB bus transaction |
begin // If there was retry, the same transaction must be initiated |
pciw_fifo_renable = 1'b0 ; // the same data |
addr_into_cnt = 1'b0 ; // the same address |
read_count_load = 1'b0 ; // no need for cache line when there is write |
n_state = S_WRITE ; |
end |
3'b100 : // Write request for PCIW_FIFO to WB bus transaction |
begin // If there is new transaction |
if (burst_chopped_delayed) |
begin |
addr_into_cnt = 1'b0 ; // address must not be latched into address counter |
pciw_fifo_renable = 1'b1 ; // first location is address (in FIFO), next will be data |
end |
else |
begin |
if (pciw_fifo_control_in[`ADDR_CTRL_BIT]) |
addr_into_cnt = 1'b1 ; // address must be latched into address counter |
else |
addr_into_cnt = 1'b0 ; |
pciw_fifo_renable = 1'b1 ; // first location is address (in FIFO), next will be data |
end |
read_count_load = 1'b0 ; // no need for cache line when there is write |
n_state = S_WRITE ; |
end |
3'b011 : // Read request from PCI Target for WB bus to PCIR_FIFO transaction |
begin // If there was retry, the same transaction must be initiated |
addr_into_cnt = 1'b0 ; // the same address |
read_count_load = 1'b0 ; // cache line counter must not be changed for retried read |
pciw_fifo_renable = 1'b0 ; // don't read from FIFO, when read transaction from WB to FIFO |
n_state = S_READ ; |
end |
3'b010 : // Read request from PCI Target for WB bus to PCIR_FIFO transaction |
begin // If there is new transaction |
addr_into_cnt = 1'b1 ; // address must be latched into counter from separate request bus |
read_count_load = 1'b1 ; // cache line size must be latched into its counter |
pciw_fifo_renable = 1'b0 ; // don't read from FIFO, when read transaction from WB to FIFO |
n_state = S_READ ; |
end |
default : // stay in IDLE state |
begin |
pciw_fifo_renable = 1'b0 ; |
addr_into_cnt = 1'b0 ; |
read_count_load = 1'b0 ; |
n_state = S_IDLE ; |
end |
endcase |
end |
S_WRITE: // WRITE from PCIW_FIFO to WB bus |
begin |
// Default values for signals not used in this state |
pcir_fifo_wenable = 1'b0 ; |
pcir_fifo_control = 4'h0 ; |
addr_into_cnt = 1'b0 ; |
read_count_load = 1'b0 ; |
read_count_enable = 1'b0 ; |
wb_read_done = 1'b0 ; |
read_rty_cnt_exp_out = 1'b0 ; |
case ({wb_ack_i, wb_err_i, wb_rty_i}) |
3'b100 : // If writting of one data is acknowledged |
begin |
addr_count = 1'b1 ; // prepare next address if there will be burst |
retried_d = 1'b0 ; // there was no retry |
pci_error_sig_out = 1'b0 ; // there was no error |
error_source_out = 1'b0 ; |
write_rty_cnt_exp_out = 1'b0 ; // there was no retry |
wait_for_wb_response = 1'b0 ; |
// if last data was transfered ! |
if (last_data_from_pciw_fifo_reg) |
begin |
n_state = S_TURN_ARROUND; |
if (~pciw_fifo_empty_in) |
pciw_fifo_renable = 1'b0 ; // prepare next value (address when new trans., data when burst tran.) |
else |
pciw_fifo_renable = 1'b0 ; |
last_data_transferred = 1'b1 ; // signal for last data transfered |
end |
// next burst data has different byte enables ! |
else if (burst_transfer && burst_chopped) |
begin |
n_state = S_IDLE ; |
pciw_fifo_renable = 1'b0 ; // next value (address when new trans., data when burst tran.) |
last_data_transferred = 1'b0 ; |
end |
else |
begin |
n_state = S_WRITE ; |
pciw_fifo_renable = 1'b1 ; // prepare next value (address when new trans., data when burst tran.) |
last_data_transferred = 1'b0 ; |
end |
end |
3'b010 : // If writting of one data is terminated with ERROR |
begin |
if (~pciw_fifo_empty_in) |
pciw_fifo_renable = 1'b1 ; // prepare next value (address when new trans., data when cleaning FIFO) |
else |
pciw_fifo_renable = 1'b0 ; |
addr_count = 1'b0 ; // no need for new address |
retried_d = 1'b0 ; // there was no retry |
last_data_transferred = 1'b1 ; // signal for last data transfered |
pci_error_sig_out = 1'b1 ; // segnal for error reporting |
error_source_out = 1'b0 ; // error source from other side of WB bus |
write_rty_cnt_exp_out = 1'b0 ; // there was no retry |
wait_for_wb_response = 1'b0 ; |
if (last_data_from_pciw_fifo_reg) // if last data was transfered |
n_state = S_TURN_ARROUND ; // go to S_TURN_ARROUND for new transfere |
else // if there wasn't last data of transfere |
n_state = S_WRITE_ERR_RTY ; // go here to clean this write transaction from PCIW_FIFO |
end |
3'b001 : // If writting of one data is retried |
begin |
addr_count = 1'b0 ; |
last_data_transferred = 1'b0 ; |
retried_d = 1'b1 ; // there was a retry |
wait_for_wb_response = 1'b0 ; |
if(rty_counter_almost_max_value) // If retry counter reached maximum allowed value |
begin |
if (last_data_from_pciw_fifo_reg) // if last data was transfered |
pciw_fifo_renable = 1'b0 ; |
else // if there wasn't last data of transfere |
pciw_fifo_renable = 1'b1 ; |
n_state = S_WRITE_ERR_RTY ; // go here to clean this write transaction from PCIW_FIFO |
write_rty_cnt_exp_out = 1'b1 ; // signal for reporting write counter expired |
pci_error_sig_out = 1'b1 ; |
error_source_out = 1'b1 ; // error ocuerd because of retry counter |
end |
else |
begin |
pciw_fifo_renable = 1'b0 ; |
n_state = S_IDLE ; // go to S_IDLE state for retrying the transaction |
write_rty_cnt_exp_out = 1'b0 ; // retry counter hasn't expired yet |
pci_error_sig_out = 1'b0 ; |
error_source_out = 1'b0 ; |
end |
end |
default : |
begin |
addr_count = 1'b0 ; |
last_data_transferred = 1'b0 ; |
wait_for_wb_response = 1'b1 ; // wait for WB device to response (after 8 clocks RTY CNT is incremented) |
error_source_out = 1'b0 ; // if error ocures, error source is from other WB bus side |
if((rty_counter_almost_max_value)&&(set_retry)) // when no WB response and RTY CNT reached maximum allowed value |
begin |
retried_d = 1'b1 ; |
if (last_data_from_pciw_fifo_reg) // if last data was transfered |
pciw_fifo_renable = 1'b0 ; |
else // if there wasn't last data of transfere |
pciw_fifo_renable = 1'b1 ; |
n_state = S_WRITE_ERR_RTY ; // go here to clean this write transaction from PCIW_FIFO |
write_rty_cnt_exp_out = 1'b1 ; // signal for reporting write counter expired |
pci_error_sig_out = 1'b1 ; // signal for error reporting |
end |
else |
begin |
pciw_fifo_renable = 1'b0 ; |
retried_d = 1'b0 ; |
n_state = S_WRITE ; // stay in S_WRITE state to wait WB to response |
write_rty_cnt_exp_out = 1'b0 ; // retry counter hasn't expired yet |
pci_error_sig_out = 1'b0 ; |
end |
end |
endcase |
end |
S_WRITE_ERR_RTY: // Clean current write transaction from PCIW_FIFO if ERROR or Retry counter expired occures |
begin |
pciw_fifo_renable = !last_data_from_pciw_fifo_reg ; // put out next data (untill last data or FIFO empty) |
last_data_transferred = 1'b1 ; // after exiting this state, negedge of this signal is used |
// Default values for signals not used in this state |
pcir_fifo_wenable = 1'b0 ; |
pcir_fifo_control = 4'h0 ; |
addr_into_cnt = 1'b0 ; |
read_count_load = 1'b0 ; |
read_count_enable = 1'b0 ; |
addr_count = 1'b0 ; |
pci_error_sig_out = 1'b0 ; |
error_source_out = 1'b0 ; |
retried_d = 1'b0 ; |
wb_read_done = 1'b0 ; |
write_rty_cnt_exp_out = 1'b0 ; |
read_rty_cnt_exp_out = 1'b0 ; |
wait_for_wb_response = 1'b0 ; |
// If last data is cleaned out from PCIW_FIFO |
if (last_data_from_pciw_fifo_reg) |
n_state = S_IDLE ; |
else |
n_state = S_WRITE_ERR_RTY ; // Clean until last data is cleaned out from FIFO |
end |
S_READ: // READ from WB bus to PCIR_FIFO |
begin |
// Default values for signals not used in this state |
pciw_fifo_renable = 1'b0 ; |
addr_into_cnt = 1'b0 ; |
read_count_load = 1'b0 ; |
pci_error_sig_out = 1'b0 ; |
error_source_out = 1'b0 ; |
write_rty_cnt_exp_out = 1'b0 ; |
case ({wb_ack_i, wb_err_i, wb_rty_i}) |
3'b100 : // If reading of one data is acknowledged |
begin |
pcir_fifo_wenable = 1'b1 ; // enable writting data into PCIR_FIFO |
addr_count = 1'b1 ; // prepare next address if there will be burst |
read_count_enable = 1'b1 ; // decrease counter value for cache line size |
retried_d = 1'b0 ; // there was no retry |
read_rty_cnt_exp_out = 1'b0 ; // there was no retry |
wait_for_wb_response = 1'b0 ; |
// if last data was transfered |
if (last_data_to_pcir_fifo) |
begin |
pcir_fifo_control[`LAST_CTRL_BIT] = 1'b1 ; // FIFO must indicate LAST data transfered |
pcir_fifo_control[`DATA_ERROR_CTRL_BIT] = 1'b0 ; |
pcir_fifo_control[`UNUSED_CTRL_BIT] = 1'b0 ; |
pcir_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ; |
last_data_transferred = 1'b1 ; // signal for last data transfered |
wb_read_done = 1'b1 ; // signal last data of read transaction for PCI Target |
n_state = S_TURN_ARROUND ; |
end |
else // if not last data transfered |
begin |
pcir_fifo_control = 4'h0 ; // ZERO for control code |
last_data_transferred = 1'b0 ; // not last data transfered |
wb_read_done = 1'b0 ; // read is not done yet |
n_state = S_READ ; |
end |
end |
3'b010 : // If reading of one data is terminated with ERROR |
begin |
pcir_fifo_wenable = 1'b1 ; // enable for writting to FIFO data with ERROR |
addr_count = 1'b0 ; // no need for new address |
pcir_fifo_control[`LAST_CTRL_BIT] = 1'b0 ; |
pcir_fifo_control[`DATA_ERROR_CTRL_BIT] = 1'b1 ; // FIFO must indicate the DATA with ERROR |
pcir_fifo_control[`UNUSED_CTRL_BIT] = 1'b0 ; |
pcir_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ; |
last_data_transferred = 1'b1 ; // signal for last data transfered |
wb_read_done = 1'b1 ; // signal last data of read transaction for PCI Target |
read_count_enable = 1'b0 ; // no need for cache line, when error occures |
n_state = S_TURN_ARROUND ; |
retried_d = 1'b0 ; // there was no retry |
wait_for_wb_response = 1'b0 ; |
read_rty_cnt_exp_out = 1'b0 ; // there was no retry |
end |
3'b001 : // If reading of one data is retried |
begin |
pcir_fifo_wenable = 1'b0 ; |
pcir_fifo_control = 4'h0 ; |
addr_count = 1'b0 ; |
read_count_enable = 1'b0 ; |
wait_for_wb_response = 1'b0 ; |
case ({first_wb_data_access, rty_counter_almost_max_value}) |
2'b10 : |
begin // if first data of the cycle (CYC_O) is retried - after each retry CYC_O goes inactive |
n_state = S_IDLE ; // go to S_IDLE state for retrying the transaction |
read_rty_cnt_exp_out = 1'b0 ; // retry counter hasn't expired yet |
last_data_transferred = 1'b0 ; |
wb_read_done = 1'b0 ; |
retried_d = 1'b1 ; // there was a retry |
end |
2'b11 : |
begin // if retry counter reached maximum value |
n_state = S_READ_RTY ; // go here to wait for PCI Target to remove read request |
read_rty_cnt_exp_out = 1'b1 ; // signal for reporting read counter expired |
last_data_transferred = 1'b0 ; |
wb_read_done = 1'b0 ; |
retried_d = 1'b1 ; // there was a retry |
end |
default : // if retry occures after at least 1 data was transferred without breaking cycle (CYC_O inactive) |
begin // then PCI device will retry access! |
n_state = S_TURN_ARROUND ; // go to S_TURN_ARROUND state |
read_rty_cnt_exp_out = 1'b0 ; // retry counter hasn't expired |
last_data_transferred = 1'b1 ; |
wb_read_done = 1'b1 ; |
retried_d = 1'b0 ; // retry must not be retried, since there is not a first data |
end |
endcase |
end |
default : |
begin |
addr_count = 1'b0 ; |
read_count_enable = 1'b0 ; |
read_rty_cnt_exp_out = 1'b0 ; |
wait_for_wb_response = 1'b1 ; // wait for WB device to response (after 8 clocks RTY CNT is incremented) |
if((rty_counter_almost_max_value)&&(set_retry)) // when no WB response and RTY CNT reached maximum allowed value |
begin |
retried_d = 1'b1 ; |
n_state = S_TURN_ARROUND ; // go here to stop read request |
pcir_fifo_wenable = 1'b1 ; |
pcir_fifo_control[`LAST_CTRL_BIT] = 1'b0 ; |
pcir_fifo_control[`DATA_ERROR_CTRL_BIT] = 1'b1 ; // FIFO must indicate the DATA with ERROR |
pcir_fifo_control[`UNUSED_CTRL_BIT] = 1'b0 ; |
pcir_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ; |
last_data_transferred = 1'b1 ; |
wb_read_done = 1'b1 ; |
end |
else |
begin |
retried_d = 1'b0 ; |
n_state = S_READ ; // stay in S_READ state to wait WB to response |
pcir_fifo_wenable = 1'b0 ; |
pcir_fifo_control = 4'h0 ; |
last_data_transferred = 1'b0 ; |
wb_read_done = 1'b0 ; |
end |
end |
endcase |
end |
S_READ_RTY: // Wait for PCI Target to remove read request, when retry counter reaches maximum value! |
begin |
// Default values for signals not used in this state |
pciw_fifo_renable = 1'b0 ; |
pcir_fifo_wenable = 1'b0 ; |
pcir_fifo_control = 4'h0 ; |
addr_into_cnt = 1'b0 ; |
read_count_load = 1'b0 ; |
read_count_enable = 1'b0 ; |
addr_count = 1'b0 ; |
pci_error_sig_out = 1'b0 ; |
error_source_out = 1'b0 ; |
retried_d = 1'b0 ; |
wb_read_done = 1'b0 ; |
write_rty_cnt_exp_out = 1'b0 ; |
read_rty_cnt_exp_out = 1'b0 ; |
wait_for_wb_response = 1'b0 ; |
// wait for PCI Target to remove read request |
if (pci_tar_read_request) |
begin |
n_state = S_READ_RTY ; // stay in this state until read request is removed |
last_data_transferred = 1'b0 ; |
end |
else // when read request is removed |
begin |
n_state = S_IDLE ; |
last_data_transferred = 1'b1 ; // when read request is removed, there is "last" data |
end |
end |
// Turn arround cycle after writting to PCIR_FIFO (for correct data when reading from PCIW_FIFO) |
default: // S_TURN_ARROUND: |
begin |
// Default values for signals not used in this state |
pciw_fifo_renable = 1'b0 ; |
pcir_fifo_wenable = 1'b0 ; |
pcir_fifo_control = 4'h0 ; |
addr_into_cnt = 1'b0 ; |
read_count_load = 1'b0 ; |
read_count_enable = 1'b0 ; |
addr_count = 1'b0 ; |
pci_error_sig_out = 1'b0 ; |
error_source_out = 1'b0 ; |
retried_d = 1'b0 ; |
last_data_transferred = 1'b1 ; |
wb_read_done = 1'b0 ; |
write_rty_cnt_exp_out = 1'b0 ; |
read_rty_cnt_exp_out = 1'b0 ; |
wait_for_wb_response = 1'b0 ; |
n_state = S_IDLE ; |
end |
endcase |
end |
|
// Signal for retry monitor in state machine when there is read and first (or single) data access |
wire ack_rty_response = wb_ack_i || wb_rty_i ; |
|
// Signal first_wb_data_access is set when no WB cycle present till end of first data access of WB cycle on WB bus |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) |
first_wb_data_access = 1'b1 ; |
else |
begin |
if (~wb_cyc_o) |
first_wb_data_access = 1'b1 ; |
else if (ack_rty_response) |
first_wb_data_access = 1'b0 ; |
end |
end |
|
// Signals to FIFO |
assign pcir_fifo_be_out = 4'hf ; // pci_tar_be ; |
|
// Signals to Conf. space |
assign pci_error_bc = bc_register ; |
|
|
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) |
wb_read_done_out <= #`FF_DELAY 1'b0 ; |
else |
wb_read_done_out <= #`FF_DELAY wb_read_done ; |
end |
|
always@(pciw_fifo_renable or addr_into_cnt_reg or pciw_fifo_control_in or pciw_fifo_empty_in) |
begin |
pciw_fifo_renable_out = pciw_fifo_renable || addr_into_cnt_reg ; |
last_data_from_pciw_fifo_reg <= #`FF_DELAY pciw_fifo_control_in[`ADDR_CTRL_BIT] || pciw_fifo_empty_in ; |
end |
|
|
endmodule |
|
/verilog/pci_bridge32.v
0,0 → 1,1542
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pci_bridge32.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// - Tadej Markovic (tadej@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.12 2003/08/21 20:49:03 tadejm |
// Added signals for WB Master B3. |
// |
// Revision 1.11 2003/08/08 16:36:33 tadejm |
// Added 'three_left_out' to pci_pciw_fifo signaling three locations before full. Added comparison between current registered cbe and next unregistered cbe to signal wb_master whether it is allowed to performe burst or not. Due to this, I needed 'three_left_out' so that writing to pci_pciw_fifo can be registered, otherwise timing problems would occure. |
// |
// Revision 1.10 2003/08/03 18:05:06 mihad |
// Added limited WISHBONE B3 support for WISHBONE Slave Unit. |
// Doesn't support full speed bursts yet. |
// |
// Revision 1.9 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.8 2002/10/21 13:04:33 mihad |
// Changed BIST signal names etc.. |
// |
// Revision 1.7 2002/10/18 03:36:37 tadejm |
// Changed wrong signal name mbist_sen into mbist_ctrl_i. |
// |
// Revision 1.6 2002/10/17 22:51:50 tadejm |
// Changed BIST signals for RAMs. |
// |
// Revision 1.5 2002/10/11 10:09:01 mihad |
// Added additional testcase and changed rst name in BIST to trst |
// |
// Revision 1.4 2002/10/08 17:17:05 mihad |
// Added BIST signals for RAMs. |
// |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// this is top level module of pci bridge core |
// it instantiates and connects other lower level modules |
// check polarity of PCI output enables in file out_reg.v and change it according to IO interface specification |
|
module pci_bridge32 |
( |
// WISHBONE system signals |
wb_clk_i, |
wb_rst_i, |
wb_rst_o, |
wb_int_i, |
wb_int_o, |
|
// WISHBONE slave interface |
wbs_adr_i, |
wbs_dat_i, |
wbs_dat_o, |
wbs_sel_i, |
wbs_cyc_i, |
wbs_stb_i, |
wbs_we_i, |
|
`ifdef PCI_WB_REV_B3 |
|
wbs_cti_i, |
wbs_bte_i, |
|
`else |
|
wbs_cab_i, |
|
`endif |
|
wbs_ack_o, |
wbs_rty_o, |
wbs_err_o, |
|
// WISHBONE master interface |
wbm_adr_o, |
wbm_dat_i, |
wbm_dat_o, |
wbm_sel_o, |
wbm_cyc_o, |
wbm_stb_o, |
wbm_we_o, |
wbm_cti_o, |
wbm_bte_o, |
wbm_ack_i, |
wbm_rty_i, |
wbm_err_i, |
|
// pci interface - system pins |
pci_clk_i, |
pci_rst_i, |
pci_rst_o, |
pci_inta_i, |
pci_inta_o, |
pci_rst_oe_o, |
pci_inta_oe_o, |
|
// arbitration pins |
pci_req_o, |
pci_req_oe_o, |
|
pci_gnt_i, |
|
// protocol pins |
pci_frame_i, |
pci_frame_o, |
|
pci_frame_oe_o, |
pci_irdy_oe_o, |
pci_devsel_oe_o, |
pci_trdy_oe_o, |
pci_stop_oe_o, |
pci_ad_oe_o, |
pci_cbe_oe_o, |
|
pci_irdy_i, |
pci_irdy_o, |
|
pci_idsel_i, |
|
pci_devsel_i, |
pci_devsel_o, |
|
pci_trdy_i, |
pci_trdy_o, |
|
pci_stop_i, |
pci_stop_o , |
|
// data transfer pins |
pci_ad_i, |
pci_ad_o, |
|
pci_cbe_i, |
pci_cbe_o, |
|
// parity generation and checking pins |
pci_par_i, |
pci_par_o, |
pci_par_oe_o, |
|
pci_perr_i, |
pci_perr_o, |
pci_perr_oe_o, |
|
// system error pin |
pci_serr_o, |
pci_serr_oe_o |
|
`ifdef PCI_BIST |
, |
// debug chain signals |
mbist_si_i, // bist scan serial in |
mbist_so_o, // bist scan serial out |
mbist_ctrl_i // bist chain shift control |
`endif |
); |
|
// WISHBONE system signals |
input wb_clk_i ; |
input wb_rst_i ; |
output wb_rst_o ; |
input wb_int_i ; |
output wb_int_o ; |
|
// WISHBONE slave interface |
input [31:0] wbs_adr_i ; |
input [31:0] wbs_dat_i ; |
output [31:0] wbs_dat_o ; |
input [3:0] wbs_sel_i ; |
input wbs_cyc_i ; |
input wbs_stb_i ; |
input wbs_we_i ; |
|
`ifdef PCI_WB_REV_B3 |
|
input [2:0] wbs_cti_i ; |
input [1:0] wbs_bte_i ; |
|
`else |
|
input wbs_cab_i ; |
|
`endif |
|
output wbs_ack_o ; |
output wbs_rty_o ; |
output wbs_err_o ; |
|
// WISHBONE master interface |
output [31:0] wbm_adr_o ; |
input [31:0] wbm_dat_i ; |
output [31:0] wbm_dat_o ; |
output [3:0] wbm_sel_o ; |
output wbm_cyc_o ; |
output wbm_stb_o ; |
output wbm_we_o ; |
output [2:0] wbm_cti_o ; |
output [1:0] wbm_bte_o ; |
input wbm_ack_i ; |
input wbm_rty_i ; |
input wbm_err_i ; |
|
// pci interface - system pins |
input pci_clk_i ; |
input pci_rst_i ; |
output pci_rst_o ; |
output pci_rst_oe_o ; |
|
input pci_inta_i ; |
output pci_inta_o ; |
output pci_inta_oe_o ; |
|
// arbitration pins |
output pci_req_o ; |
output pci_req_oe_o ; |
|
input pci_gnt_i ; |
|
// protocol pins |
input pci_frame_i ; |
output pci_frame_o ; |
output pci_frame_oe_o ; |
output pci_irdy_oe_o ; |
output pci_devsel_oe_o ; |
output pci_trdy_oe_o ; |
output pci_stop_oe_o ; |
output [31:0] pci_ad_oe_o ; |
output [3:0] pci_cbe_oe_o ; |
|
input pci_irdy_i ; |
output pci_irdy_o ; |
|
input pci_idsel_i ; |
|
input pci_devsel_i ; |
output pci_devsel_o ; |
|
input pci_trdy_i ; |
output pci_trdy_o ; |
|
input pci_stop_i ; |
output pci_stop_o ; |
|
// data transfer pins |
input [31:0] pci_ad_i ; |
output [31:0] pci_ad_o ; |
|
input [3:0] pci_cbe_i ; |
output [3:0] pci_cbe_o ; |
|
// parity generation and checking pins |
input pci_par_i ; |
output pci_par_o ; |
output pci_par_oe_o ; |
|
input pci_perr_i ; |
output pci_perr_o ; |
output pci_perr_oe_o ; |
|
// system error pin |
output pci_serr_o ; |
output pci_serr_oe_o ; |
|
`ifdef PCI_BIST |
/*----------------------------------------------------- |
BIST debug chain port signals |
-----------------------------------------------------*/ |
input mbist_si_i; // bist scan serial in |
output mbist_so_o; // bist scan serial out |
input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control |
|
// internal wires for serial chain connection |
wire SO_internal ; |
wire SI_internal = SO_internal ; |
`endif |
|
// declare clock and reset wires |
wire pci_clk = pci_clk_i ; |
wire wb_clk = wb_clk_i ; |
wire reset ; // assigned at pci bridge reset and interrupt logic |
|
/*========================================================================================================= |
First comes definition of all modules' outputs, so they can be assigned to any other module's input later |
in the file, when module is instantiated |
=========================================================================================================*/ |
// PCI BRIDGE RESET AND INTERRUPT LOGIC OUTPUTS |
wire pci_reso_reset ; |
wire pci_reso_pci_rstn_out ; |
wire pci_reso_pci_rstn_en_out ; |
wire pci_reso_rst_o ; |
wire pci_into_pci_intan_out ; |
wire pci_into_pci_intan_en_out ; |
wire pci_into_int_o ; |
wire pci_into_conf_isr_int_prop_out ; |
|
// assign pci bridge reset interrupt logic outputs to top outputs where possible |
assign reset = pci_reso_reset ; |
assign pci_rst_o = pci_reso_pci_rstn_out ; |
assign pci_rst_oe_o = pci_reso_pci_rstn_en_out ; |
assign wb_rst_o = pci_reso_rst_o ; |
assign pci_inta_o = pci_into_pci_intan_out ; |
assign pci_inta_oe_o = pci_into_pci_intan_en_out ; |
assign wb_int_o = pci_into_int_o ; |
|
// WISHBONE SLAVE UNIT OUTPUTS |
wire [31:0] wbu_sdata_out ; |
wire wbu_ack_out ; |
wire wbu_rty_out ; |
wire wbu_err_out ; |
wire wbu_pciif_req_out ; |
wire wbu_pciif_frame_out ; |
wire wbu_pciif_frame_en_out ; |
wire wbu_pciif_irdy_out ; |
wire wbu_pciif_irdy_en_out ; |
wire [31:0] wbu_pciif_ad_out ; |
wire wbu_pciif_ad_en_out ; |
wire [3:0] wbu_pciif_cbe_out ; |
wire wbu_pciif_cbe_en_out ; |
wire [31:0] wbu_err_addr_out ; |
wire [3:0] wbu_err_bc_out ; |
wire wbu_err_signal_out ; |
wire wbu_err_source_out ; |
wire wbu_err_rty_exp_out ; |
wire wbu_tabort_rec_out ; |
wire wbu_mabort_rec_out ; |
wire [11:0] wbu_conf_offset_out ; |
wire wbu_conf_renable_out ; |
wire wbu_conf_wenable_out ; |
wire [3:0] wbu_conf_be_out ; |
wire [31:0] wbu_conf_data_out ; |
wire wbu_del_read_comp_pending_out ; |
wire wbu_wbw_fifo_empty_out ; |
wire wbu_ad_load_out ; |
wire wbu_ad_load_on_transfer_out ; |
wire wbu_pciif_frame_load_out ; |
|
// PCI TARGET UNIT OUTPUTS |
wire [31:0] pciu_adr_out ; |
wire [31:0] pciu_mdata_out ; |
wire pciu_cyc_out ; |
wire pciu_stb_out ; |
wire pciu_we_out ; |
wire [2:0] pciu_cti_out ; |
wire [1:0] pciu_bte_out ; |
wire [3:0] pciu_sel_out ; |
wire pciu_pciif_trdy_out ; |
wire pciu_pciif_stop_out ; |
wire pciu_pciif_devsel_out ; |
wire pciu_pciif_trdy_en_out ; |
wire pciu_pciif_stop_en_out ; |
wire pciu_pciif_devsel_en_out ; |
wire pciu_ad_load_out ; |
wire pciu_ad_load_on_transfer_out ; |
wire [31:0] pciu_pciif_ad_out ; |
wire pciu_pciif_ad_en_out ; |
wire pciu_pciif_tabort_set_out ; |
wire [31:0] pciu_err_addr_out ; |
wire [3:0] pciu_err_bc_out ; |
wire [31:0] pciu_err_data_out ; |
wire [3:0] pciu_err_be_out ; |
wire pciu_err_signal_out ; |
wire pciu_err_source_out ; |
wire pciu_err_rty_exp_out ; |
wire pciu_conf_select_out ; |
wire [11:0] pciu_conf_offset_out ; |
wire pciu_conf_renable_out ; |
wire pciu_conf_wenable_out ; |
wire [3:0] pciu_conf_be_out ; |
wire [31:0] pciu_conf_data_out ; |
wire pciu_pci_drcomp_pending_out ; |
wire pciu_pciw_fifo_empty_out ; |
|
// assign pci target unit's outputs to top outputs where possible |
assign wbm_adr_o = pciu_adr_out ; |
assign wbm_dat_o = pciu_mdata_out ; |
assign wbm_cyc_o = pciu_cyc_out ; |
assign wbm_stb_o = pciu_stb_out ; |
assign wbm_we_o = pciu_we_out ; |
assign wbm_cti_o = pciu_cti_out ; |
assign wbm_bte_o = pciu_bte_out ; |
assign wbm_sel_o = pciu_sel_out ; |
|
// CONFIGURATION SPACE OUTPUTS |
wire [31:0] conf_w_data_out ; |
wire [31:0] conf_r_data_out ; |
wire conf_serr_enable_out ; |
wire conf_perr_response_out ; |
wire conf_pci_master_enable_out ; |
wire conf_mem_space_enable_out ; |
wire conf_io_space_enable_out ; |
wire [7:0] conf_cache_line_size_to_pci_out ; |
wire [7:0] conf_cache_line_size_to_wb_out ; |
wire conf_cache_lsize_not_zero_to_wb_out ; |
wire [7:0] conf_latency_tim_out ; |
|
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ba0_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ba1_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ba2_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ba3_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ba4_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ba5_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ta0_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ta1_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ta2_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ta3_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ta4_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_ta5_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_am0_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_am1_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_am2_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_am3_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_am4_out ; |
wire [19:(20 - `PCI_NUM_OF_DEC_ADDR_LINES)] conf_pci_am5_out ; |
|
wire conf_pci_mem_io0_out ; |
wire conf_pci_mem_io1_out ; |
wire conf_pci_mem_io2_out ; |
wire conf_pci_mem_io3_out ; |
wire conf_pci_mem_io4_out ; |
wire conf_pci_mem_io5_out ; |
|
wire [1:0] conf_pci_img_ctrl0_out ; |
wire [1:0] conf_pci_img_ctrl1_out ; |
wire [1:0] conf_pci_img_ctrl2_out ; |
wire [1:0] conf_pci_img_ctrl3_out ; |
wire [1:0] conf_pci_img_ctrl4_out ; |
wire [1:0] conf_pci_img_ctrl5_out ; |
|
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba0_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba1_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba2_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba3_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba4_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba5_out ; |
|
wire conf_wb_mem_io0_out ; |
wire conf_wb_mem_io1_out ; |
wire conf_wb_mem_io2_out ; |
wire conf_wb_mem_io3_out ; |
wire conf_wb_mem_io4_out ; |
wire conf_wb_mem_io5_out ; |
|
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am0_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am1_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am2_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am3_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am4_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am5_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta0_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta1_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta2_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta3_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta4_out ; |
wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta5_out ; |
wire [2:0] conf_wb_img_ctrl0_out ; |
wire [2:0] conf_wb_img_ctrl1_out ; |
wire [2:0] conf_wb_img_ctrl2_out ; |
wire [2:0] conf_wb_img_ctrl3_out ; |
wire [2:0] conf_wb_img_ctrl4_out ; |
wire [2:0] conf_wb_img_ctrl5_out ; |
wire [23:0] conf_ccyc_addr_out ; |
wire conf_soft_res_out ; |
wire conf_int_out ; |
|
// PCI IO MUX OUTPUTS |
wire pci_mux_frame_out ; |
wire pci_mux_irdy_out ; |
wire pci_mux_devsel_out ; |
wire pci_mux_trdy_out ; |
wire pci_mux_stop_out ; |
wire [3:0] pci_mux_cbe_out ; |
wire [31:0] pci_mux_ad_out ; |
wire pci_mux_ad_load_out ; |
|
wire [31:0] pci_mux_ad_en_out ; |
wire pci_mux_ad_en_unregistered_out ; |
wire pci_mux_frame_en_out ; |
wire pci_mux_irdy_en_out ; |
wire pci_mux_devsel_en_out ; |
wire pci_mux_trdy_en_out ; |
wire pci_mux_stop_en_out ; |
wire [3:0] pci_mux_cbe_en_out ; |
|
wire pci_mux_par_out ; |
wire pci_mux_par_en_out ; |
wire pci_mux_perr_out ; |
wire pci_mux_perr_en_out ; |
wire pci_mux_serr_out ; |
wire pci_mux_serr_en_out ; |
|
wire pci_mux_req_out ; |
wire pci_mux_req_en_out ; |
|
// assign outputs to top level outputs |
|
assign pci_ad_oe_o = pci_mux_ad_en_out ; |
assign pci_frame_oe_o = pci_mux_frame_en_out ; |
assign pci_irdy_oe_o = pci_mux_irdy_en_out ; |
assign pci_cbe_oe_o = pci_mux_cbe_en_out ; |
|
assign pci_par_o = pci_mux_par_out ; |
assign pci_par_oe_o = pci_mux_par_en_out ; |
assign pci_perr_o = pci_mux_perr_out ; |
assign pci_perr_oe_o = pci_mux_perr_en_out ; |
assign pci_serr_o = pci_mux_serr_out ; |
assign pci_serr_oe_o = pci_mux_serr_en_out ; |
|
assign pci_req_o = pci_mux_req_out ; |
assign pci_req_oe_o = pci_mux_req_en_out ; |
|
assign pci_trdy_oe_o = pci_mux_trdy_en_out ; |
assign pci_devsel_oe_o = pci_mux_devsel_en_out ; |
assign pci_stop_oe_o = pci_mux_stop_en_out ; |
assign pci_trdy_o = pci_mux_trdy_out ; |
assign pci_devsel_o = pci_mux_devsel_out ; |
assign pci_stop_o = pci_mux_stop_out ; |
|
assign pci_ad_o = pci_mux_ad_out ; |
assign pci_frame_o = pci_mux_frame_out ; |
assign pci_irdy_o = pci_mux_irdy_out ; |
assign pci_cbe_o = pci_mux_cbe_out ; |
|
// duplicate output register's outputs |
wire out_bckp_frame_out ; |
wire out_bckp_irdy_out ; |
wire out_bckp_devsel_out ; |
wire out_bckp_trdy_out ; |
wire out_bckp_stop_out ; |
wire [3:0] out_bckp_cbe_out ; |
wire out_bckp_cbe_en_out ; |
wire [31:0] out_bckp_ad_out ; |
wire out_bckp_ad_en_out ; |
wire out_bckp_irdy_en_out ; |
wire out_bckp_frame_en_out ; |
wire out_bckp_tar_ad_en_out ; |
wire out_bckp_mas_ad_en_out ; |
wire out_bckp_trdy_en_out ; |
|
wire out_bckp_par_out ; |
wire out_bckp_par_en_out ; |
wire out_bckp_perr_out ; |
wire out_bckp_perr_en_out ; |
wire out_bckp_serr_out ; |
wire out_bckp_serr_en_out ; |
|
|
// PARITY CHECKER OUTPUTS |
wire parchk_pci_par_out ; |
wire parchk_pci_par_en_out ; |
wire parchk_pci_perr_out ; |
wire parchk_pci_perr_en_out ; |
wire parchk_pci_serr_out ; |
wire parchk_pci_serr_en_out ; |
wire parchk_par_err_detect_out ; |
wire parchk_perr_mas_detect_out ; |
wire parchk_sig_serr_out ; |
|
// input register outputs |
wire in_reg_gnt_out ; |
wire in_reg_frame_out ; |
wire in_reg_irdy_out ; |
wire in_reg_trdy_out ; |
wire in_reg_stop_out ; |
wire in_reg_devsel_out ; |
wire in_reg_idsel_out ; |
wire [31:0] in_reg_ad_out ; |
wire [3:0] in_reg_cbe_out ; |
|
/*========================================================================================================= |
Now comes definition of all modules' and their appropriate inputs |
=========================================================================================================*/ |
// PCI BRIDGE RESET AND INTERRUPT LOGIC INPUTS |
wire pci_resi_rst_i = wb_rst_i ; |
wire pci_resi_pci_rstn_in = pci_rst_i ; |
wire pci_resi_conf_soft_res_in = conf_soft_res_out ; |
wire pci_inti_pci_intan_in = pci_inta_i ; |
wire pci_inti_conf_int_in = conf_int_out ; |
wire pci_inti_int_i = wb_int_i ; |
wire pci_inti_out_bckp_perr_en_in = out_bckp_perr_en_out ; |
wire pci_inti_out_bckp_serr_en_in = out_bckp_serr_en_out ; |
|
pci_rst_int pci_resets_and_interrupts |
( |
.clk_in (pci_clk), |
.rst_i (pci_resi_rst_i), |
.pci_rstn_in (pci_resi_pci_rstn_in), |
.conf_soft_res_in (pci_resi_conf_soft_res_in), |
.reset (pci_reso_reset), |
.pci_rstn_out (pci_reso_pci_rstn_out), |
.pci_rstn_en_out (pci_reso_pci_rstn_en_out), |
.rst_o (pci_reso_rst_o), |
.pci_intan_in (pci_inti_pci_intan_in), |
.conf_int_in (pci_inti_conf_int_in), |
.int_i (pci_inti_int_i), |
.out_bckp_perr_en_in (pci_inti_out_bckp_perr_en_in), |
.out_bckp_serr_en_in (pci_inti_out_bckp_serr_en_in), |
.pci_intan_out (pci_into_pci_intan_out), |
.pci_intan_en_out (pci_into_pci_intan_en_out), |
.int_o (pci_into_int_o), |
.conf_isr_int_prop_out (pci_into_conf_isr_int_prop_out) |
); |
|
|
`ifdef PCI_WB_REV_B3 |
|
wire wbs_wbb3_2_wbb2_cyc_o ; |
wire wbs_wbb3_2_wbb2_stb_o ; |
wire [31:0] wbs_wbb3_2_wbb2_adr_o ; |
wire [31:0] wbs_wbb3_2_wbb2_dat_i_o ; |
wire [31:0] wbs_wbb3_2_wbb2_dat_o_o ; |
wire wbs_wbb3_2_wbb2_we_o ; |
wire [ 3:0] wbs_wbb3_2_wbb2_sel_o ; |
wire wbs_wbb3_2_wbb2_ack_o ; |
wire wbs_wbb3_2_wbb2_err_o ; |
wire wbs_wbb3_2_wbb2_rty_o ; |
wire wbs_wbb3_2_wbb2_cab_o ; |
|
// assign wishbone slave unit's outputs to top outputs where possible |
assign wbs_dat_o = wbs_wbb3_2_wbb2_dat_o_o ; |
assign wbs_ack_o = wbs_wbb3_2_wbb2_ack_o ; |
assign wbs_rty_o = wbs_wbb3_2_wbb2_rty_o ; |
assign wbs_err_o = wbs_wbb3_2_wbb2_err_o ; |
|
wire wbs_wbb3_2_wbb2_cyc_i = wbs_cyc_i ; |
wire wbs_wbb3_2_wbb2_stb_i = wbs_stb_i ; |
wire wbs_wbb3_2_wbb2_we_i = wbs_we_i ; |
wire wbs_wbb3_2_wbb2_ack_i = wbu_ack_out ; |
wire wbs_wbb3_2_wbb2_err_i = wbu_err_out ; |
wire wbs_wbb3_2_wbb2_rty_i = wbu_rty_out ; |
wire [31:0] wbs_wbb3_2_wbb2_adr_i = wbs_adr_i ; |
wire [ 3:0] wbs_wbb3_2_wbb2_sel_i = wbs_sel_i ; |
wire [31:0] wbs_wbb3_2_wbb2_dat_i_i = wbs_dat_i ; |
wire [31:0] wbs_wbb3_2_wbb2_dat_o_i = wbu_sdata_out ; |
wire [ 2:0] wbs_wbb3_2_wbb2_cti_i = wbs_cti_i ; |
wire [ 1:0] wbs_wbb3_2_wbb2_bte_i = wbs_bte_i ; |
|
pci_wbs_wbb3_2_wbb2 i_pci_wbs_wbb3_2_wbb2 |
( |
.wb_clk_i ( wb_clk_i ) , |
.wb_rst_i ( wb_rst_i ) , |
|
.wbs_cyc_i ( wbs_wbb3_2_wbb2_cyc_i ) , |
.wbs_cyc_o ( wbs_wbb3_2_wbb2_cyc_o ) , |
.wbs_stb_i ( wbs_wbb3_2_wbb2_stb_i ) , |
.wbs_stb_o ( wbs_wbb3_2_wbb2_stb_o ) , |
.wbs_adr_i ( wbs_wbb3_2_wbb2_adr_i ) , |
.wbs_adr_o ( wbs_wbb3_2_wbb2_adr_o ) , |
.wbs_dat_i_i ( wbs_wbb3_2_wbb2_dat_i_i ) , |
.wbs_dat_i_o ( wbs_wbb3_2_wbb2_dat_i_o ) , |
.wbs_dat_o_i ( wbs_wbb3_2_wbb2_dat_o_i ) , |
.wbs_dat_o_o ( wbs_wbb3_2_wbb2_dat_o_o ) , |
.wbs_we_i ( wbs_wbb3_2_wbb2_we_i ) , |
.wbs_we_o ( wbs_wbb3_2_wbb2_we_o ) , |
.wbs_sel_i ( wbs_wbb3_2_wbb2_sel_i ) , |
.wbs_sel_o ( wbs_wbb3_2_wbb2_sel_o ) , |
.wbs_ack_i ( wbs_wbb3_2_wbb2_ack_i ) , |
.wbs_ack_o ( wbs_wbb3_2_wbb2_ack_o ) , |
.wbs_err_i ( wbs_wbb3_2_wbb2_err_i ) , |
.wbs_err_o ( wbs_wbb3_2_wbb2_err_o ) , |
.wbs_rty_i ( wbs_wbb3_2_wbb2_rty_i ) , |
.wbs_rty_o ( wbs_wbb3_2_wbb2_rty_o ) , |
.wbs_cti_i ( wbs_wbb3_2_wbb2_cti_i ) , |
.wbs_bte_i ( wbs_wbb3_2_wbb2_bte_i ) , |
.wbs_cab_o ( wbs_wbb3_2_wbb2_cab_o ) |
) ; |
|
// WISHBONE SLAVE UNIT INPUTS |
wire [31:0] wbu_addr_in = wbs_wbb3_2_wbb2_adr_o ; |
wire [31:0] wbu_sdata_in = wbs_wbb3_2_wbb2_dat_i_o ; |
wire wbu_cyc_in = wbs_wbb3_2_wbb2_cyc_o ; |
wire wbu_stb_in = wbs_wbb3_2_wbb2_stb_o ; |
wire wbu_we_in = wbs_wbb3_2_wbb2_we_o ; |
wire [3:0] wbu_sel_in = wbs_wbb3_2_wbb2_sel_o ; |
wire wbu_cab_in = wbs_wbb3_2_wbb2_cab_o ; |
|
`else |
|
// WISHBONE SLAVE UNIT INPUTS |
wire [31:0] wbu_addr_in = wbs_adr_i ; |
wire [31:0] wbu_sdata_in = wbs_dat_i ; |
wire wbu_cyc_in = wbs_cyc_i ; |
wire wbu_stb_in = wbs_stb_i ; |
wire wbu_we_in = wbs_we_i ; |
wire [3:0] wbu_sel_in = wbs_sel_i ; |
wire wbu_cab_in = wbs_cab_i ; |
|
// assign wishbone slave unit's outputs to top outputs where possible |
assign wbs_dat_o = wbu_sdata_out ; |
assign wbs_ack_o = wbu_ack_out ; |
assign wbs_rty_o = wbu_rty_out ; |
assign wbs_err_o = wbu_err_out ; |
|
`endif |
|
wire [5:0] wbu_map_in = { |
conf_wb_mem_io5_out, |
conf_wb_mem_io4_out, |
conf_wb_mem_io3_out, |
conf_wb_mem_io2_out, |
conf_wb_mem_io1_out, |
conf_wb_mem_io0_out |
} ; |
|
wire [5:0] wbu_pref_en_in = { |
conf_wb_img_ctrl5_out[1], |
conf_wb_img_ctrl4_out[1], |
conf_wb_img_ctrl3_out[1], |
conf_wb_img_ctrl2_out[1], |
conf_wb_img_ctrl1_out[1], |
conf_wb_img_ctrl0_out[1] |
}; |
wire [5:0] wbu_mrl_en_in = { |
conf_wb_img_ctrl5_out[0], |
conf_wb_img_ctrl4_out[0], |
conf_wb_img_ctrl3_out[0], |
conf_wb_img_ctrl2_out[0], |
conf_wb_img_ctrl1_out[0], |
conf_wb_img_ctrl0_out[0] |
}; |
|
wire [5:0] wbu_at_en_in = { |
conf_wb_img_ctrl5_out[2], |
conf_wb_img_ctrl4_out[2], |
conf_wb_img_ctrl3_out[2], |
conf_wb_img_ctrl2_out[2], |
conf_wb_img_ctrl1_out[2], |
conf_wb_img_ctrl0_out[2] |
} ; |
|
wire wbu_pci_drcomp_pending_in = pciu_pci_drcomp_pending_out ; |
wire wbu_pciw_empty_in = pciu_pciw_fifo_empty_out ; |
|
`ifdef HOST |
wire [31:0] wbu_conf_data_in = conf_w_data_out ; |
`else |
`ifdef GUEST |
wire [31:0] wbu_conf_data_in = conf_r_data_out ; |
`endif |
`endif |
|
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar0_in = conf_wb_ba0_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar1_in = conf_wb_ba1_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar2_in = conf_wb_ba2_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar3_in = conf_wb_ba3_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar4_in = conf_wb_ba4_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar5_in = conf_wb_ba5_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am0_in = conf_wb_am0_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am1_in = conf_wb_am1_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am2_in = conf_wb_am2_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am3_in = conf_wb_am3_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am4_in = conf_wb_am4_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am5_in = conf_wb_am5_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta0_in = conf_wb_ta0_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta1_in = conf_wb_ta1_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta2_in = conf_wb_ta2_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta3_in = conf_wb_ta3_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta4_in = conf_wb_ta4_out ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta5_in = conf_wb_ta5_out ; |
|
wire [23:0] wbu_ccyc_addr_in = conf_ccyc_addr_out ; |
wire wbu_master_enable_in = conf_pci_master_enable_out ; |
wire wbu_cache_line_size_not_zero = conf_cache_lsize_not_zero_to_wb_out ; |
wire [7:0] wbu_cache_line_size_in = conf_cache_line_size_to_pci_out ; |
|
wire wbu_pciif_gnt_in = pci_gnt_i ; |
wire wbu_pciif_frame_in = in_reg_frame_out ; |
wire wbu_pciif_irdy_in = in_reg_irdy_out ; |
wire wbu_pciif_trdy_in = pci_trdy_i ; |
wire wbu_pciif_stop_in = pci_stop_i ; |
wire wbu_pciif_devsel_in = pci_devsel_i ; |
wire [31:0] wbu_pciif_ad_reg_in = in_reg_ad_out ; |
wire wbu_pciif_trdy_reg_in = in_reg_trdy_out ; |
wire wbu_pciif_stop_reg_in = in_reg_stop_out ; |
wire wbu_pciif_devsel_reg_in = in_reg_devsel_out ; |
|
|
wire [7:0] wbu_latency_tim_val_in = conf_latency_tim_out ; |
|
wire wbu_pciif_frame_en_in = out_bckp_frame_en_out ; |
wire wbu_pciif_frame_out_in = out_bckp_frame_out ; |
|
pci_wb_slave_unit wishbone_slave_unit |
( |
.reset_in (reset), |
.wb_clock_in (wb_clk), |
.pci_clock_in (pci_clk), |
.ADDR_I (wbu_addr_in), |
.SDATA_I (wbu_sdata_in), |
.SDATA_O (wbu_sdata_out), |
.CYC_I (wbu_cyc_in), |
.STB_I (wbu_stb_in), |
.WE_I (wbu_we_in), |
.SEL_I (wbu_sel_in), |
.ACK_O (wbu_ack_out), |
.RTY_O (wbu_rty_out), |
.ERR_O (wbu_err_out), |
.CAB_I (wbu_cab_in), |
.wbu_map_in (wbu_map_in), |
.wbu_pref_en_in (wbu_pref_en_in), |
.wbu_mrl_en_in (wbu_mrl_en_in), |
.wbu_pci_drcomp_pending_in (wbu_pci_drcomp_pending_in), |
.wbu_conf_data_in (wbu_conf_data_in), |
.wbu_pciw_empty_in (wbu_pciw_empty_in), |
.wbu_bar0_in (wbu_bar0_in), |
.wbu_bar1_in (wbu_bar1_in), |
.wbu_bar2_in (wbu_bar2_in), |
.wbu_bar3_in (wbu_bar3_in), |
.wbu_bar4_in (wbu_bar4_in), |
.wbu_bar5_in (wbu_bar5_in), |
.wbu_am0_in (wbu_am0_in), |
.wbu_am1_in (wbu_am1_in), |
.wbu_am2_in (wbu_am2_in), |
.wbu_am3_in (wbu_am3_in), |
.wbu_am4_in (wbu_am4_in), |
.wbu_am5_in (wbu_am5_in), |
.wbu_ta0_in (wbu_ta0_in), |
.wbu_ta1_in (wbu_ta1_in), |
.wbu_ta2_in (wbu_ta2_in), |
.wbu_ta3_in (wbu_ta3_in), |
.wbu_ta4_in (wbu_ta4_in), |
.wbu_ta5_in (wbu_ta5_in), |
.wbu_at_en_in (wbu_at_en_in), |
.wbu_ccyc_addr_in (wbu_ccyc_addr_in), |
.wbu_master_enable_in (wbu_master_enable_in), |
.wbu_cache_line_size_not_zero (wbu_cache_line_size_not_zero), |
.wbu_cache_line_size_in (wbu_cache_line_size_in), |
.wbu_pciif_gnt_in (wbu_pciif_gnt_in), |
.wbu_pciif_frame_in (wbu_pciif_frame_in), |
.wbu_pciif_frame_en_in (wbu_pciif_frame_en_in), |
.wbu_pciif_frame_out_in (wbu_pciif_frame_out_in), |
.wbu_pciif_irdy_in (wbu_pciif_irdy_in), |
.wbu_pciif_trdy_in (wbu_pciif_trdy_in), |
.wbu_pciif_stop_in (wbu_pciif_stop_in), |
.wbu_pciif_devsel_in (wbu_pciif_devsel_in), |
.wbu_pciif_ad_reg_in (wbu_pciif_ad_reg_in), |
.wbu_pciif_req_out (wbu_pciif_req_out), |
.wbu_pciif_frame_out (wbu_pciif_frame_out), |
.wbu_pciif_frame_en_out (wbu_pciif_frame_en_out), |
.wbu_pciif_frame_load_out (wbu_pciif_frame_load_out), |
.wbu_pciif_irdy_out (wbu_pciif_irdy_out), |
.wbu_pciif_irdy_en_out (wbu_pciif_irdy_en_out), |
.wbu_pciif_ad_out (wbu_pciif_ad_out), |
.wbu_pciif_ad_en_out (wbu_pciif_ad_en_out), |
.wbu_pciif_cbe_out (wbu_pciif_cbe_out), |
.wbu_pciif_cbe_en_out (wbu_pciif_cbe_en_out), |
.wbu_err_addr_out (wbu_err_addr_out), |
.wbu_err_bc_out (wbu_err_bc_out), |
.wbu_err_signal_out (wbu_err_signal_out), |
.wbu_err_source_out (wbu_err_source_out), |
.wbu_err_rty_exp_out (wbu_err_rty_exp_out), |
.wbu_tabort_rec_out (wbu_tabort_rec_out), |
.wbu_mabort_rec_out (wbu_mabort_rec_out), |
.wbu_conf_offset_out (wbu_conf_offset_out), |
.wbu_conf_renable_out (wbu_conf_renable_out), |
.wbu_conf_wenable_out (wbu_conf_wenable_out), |
.wbu_conf_be_out (wbu_conf_be_out), |
.wbu_conf_data_out (wbu_conf_data_out), |
.wbu_del_read_comp_pending_out (wbu_del_read_comp_pending_out), |
.wbu_wbw_fifo_empty_out (wbu_wbw_fifo_empty_out), |
.wbu_latency_tim_val_in (wbu_latency_tim_val_in), |
.wbu_ad_load_out (wbu_ad_load_out), |
.wbu_ad_load_on_transfer_out (wbu_ad_load_on_transfer_out), |
.wbu_pciif_trdy_reg_in (wbu_pciif_trdy_reg_in), |
.wbu_pciif_stop_reg_in (wbu_pciif_stop_reg_in), |
.wbu_pciif_devsel_reg_in (wbu_pciif_devsel_reg_in) |
|
`ifdef PCI_BIST |
, |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o_internal), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
); |
|
// PCI TARGET UNIT INPUTS |
wire [31:0] pciu_mdata_in = wbm_dat_i ; |
wire pciu_ack_in = wbm_ack_i ; |
wire pciu_rty_in = wbm_rty_i ; |
wire pciu_err_in = wbm_err_i ; |
|
wire [5:0] pciu_map_in = { |
conf_pci_mem_io5_out, |
conf_pci_mem_io4_out, |
conf_pci_mem_io3_out, |
conf_pci_mem_io2_out, |
conf_pci_mem_io1_out, |
conf_pci_mem_io0_out |
} ; |
|
wire [5:0] pciu_pref_en_in = { |
conf_pci_img_ctrl5_out[0], |
conf_pci_img_ctrl4_out[0], |
conf_pci_img_ctrl3_out[0], |
conf_pci_img_ctrl2_out[0], |
conf_pci_img_ctrl1_out[0], |
conf_pci_img_ctrl0_out[0] |
}; |
|
wire [5:0] pciu_at_en_in = { |
conf_pci_img_ctrl5_out[1], |
conf_pci_img_ctrl4_out[1], |
conf_pci_img_ctrl3_out[1], |
conf_pci_img_ctrl2_out[1], |
conf_pci_img_ctrl1_out[1], |
conf_pci_img_ctrl0_out[1] |
} ; |
|
wire pciu_mem_enable_in = conf_mem_space_enable_out ; |
wire pciu_io_enable_in = conf_io_space_enable_out ; |
|
wire pciu_wbw_fifo_empty_in = wbu_wbw_fifo_empty_out ; |
wire pciu_wbu_del_read_comp_pending_in = wbu_del_read_comp_pending_out ; |
wire pciu_wbu_frame_en_in = out_bckp_frame_en_out ; |
|
`ifdef HOST |
wire [31:0] pciu_conf_data_in = conf_r_data_out ; |
`else |
`ifdef GUEST |
wire [31:0] pciu_conf_data_in = conf_w_data_out ; |
`endif |
`endif |
|
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar0_in = conf_pci_ba0_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar1_in = conf_pci_ba1_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar2_in = conf_pci_ba2_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar3_in = conf_pci_ba3_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar4_in = conf_pci_ba4_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar5_in = conf_pci_ba5_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am0_in = conf_pci_am0_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am1_in = conf_pci_am1_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am2_in = conf_pci_am2_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am3_in = conf_pci_am3_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am4_in = conf_pci_am4_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am5_in = conf_pci_am5_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta0_in = conf_pci_ta0_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta1_in = conf_pci_ta1_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta2_in = conf_pci_ta2_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta3_in = conf_pci_ta3_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta4_in = conf_pci_ta4_out ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta5_in = conf_pci_ta5_out ; |
|
wire [7:0] pciu_cache_line_size_in = conf_cache_line_size_to_wb_out ; |
wire pciu_cache_lsize_not_zero_in = conf_cache_lsize_not_zero_to_wb_out ; |
|
wire pciu_pciif_frame_in = pci_frame_i ; |
wire pciu_pciif_irdy_in = pci_irdy_i ; |
wire pciu_pciif_idsel_in = pci_idsel_i ; |
wire pciu_pciif_frame_reg_in = in_reg_frame_out ; |
wire pciu_pciif_irdy_reg_in = in_reg_irdy_out ; |
wire pciu_pciif_idsel_reg_in = in_reg_idsel_out ; |
wire [31:0] pciu_pciif_ad_reg_in = in_reg_ad_out ; |
wire [3:0] pciu_pciif_cbe_reg_in = in_reg_cbe_out ; |
wire [3:0] pciu_pciif_cbe_in = pci_cbe_i ; |
|
wire pciu_pciif_bckp_trdy_en_in = out_bckp_trdy_en_out ; |
wire pciu_pciif_bckp_devsel_in = out_bckp_devsel_out ; |
wire pciu_pciif_bckp_trdy_in = out_bckp_trdy_out ; |
wire pciu_pciif_bckp_stop_in = out_bckp_stop_out ; |
wire pciu_pciif_trdy_reg_in = in_reg_trdy_out ; |
wire pciu_pciif_stop_reg_in = in_reg_stop_out ; |
|
pci_target_unit pci_target_unit |
( |
.reset_in (reset), |
.wb_clock_in (wb_clk), |
.pci_clock_in (pci_clk), |
.pciu_wbm_adr_o (pciu_adr_out), |
.pciu_wbm_dat_o (pciu_mdata_out), |
.pciu_wbm_dat_i (pciu_mdata_in), |
.pciu_wbm_cyc_o (pciu_cyc_out), |
.pciu_wbm_stb_o (pciu_stb_out), |
.pciu_wbm_we_o (pciu_we_out), |
.pciu_wbm_cti_o (pciu_cti_out), |
.pciu_wbm_bte_o (pciu_bte_out), |
.pciu_wbm_sel_o (pciu_sel_out), |
.pciu_wbm_ack_i (pciu_ack_in), |
.pciu_wbm_rty_i (pciu_rty_in), |
.pciu_wbm_err_i (pciu_err_in), |
.pciu_mem_enable_in (pciu_mem_enable_in), |
.pciu_io_enable_in (pciu_io_enable_in), |
.pciu_map_in (pciu_map_in), |
.pciu_pref_en_in (pciu_pref_en_in), |
.pciu_conf_data_in (pciu_conf_data_in), |
.pciu_wbw_fifo_empty_in (pciu_wbw_fifo_empty_in), |
.pciu_wbu_del_read_comp_pending_in (pciu_wbu_del_read_comp_pending_in), |
.pciu_wbu_frame_en_in (pciu_wbu_frame_en_in), |
.pciu_bar0_in (pciu_bar0_in), |
.pciu_bar1_in (pciu_bar1_in), |
.pciu_bar2_in (pciu_bar2_in), |
.pciu_bar3_in (pciu_bar3_in), |
.pciu_bar4_in (pciu_bar4_in), |
.pciu_bar5_in (pciu_bar5_in), |
.pciu_am0_in (pciu_am0_in), |
.pciu_am1_in (pciu_am1_in), |
.pciu_am2_in (pciu_am2_in), |
.pciu_am3_in (pciu_am3_in), |
.pciu_am4_in (pciu_am4_in), |
.pciu_am5_in (pciu_am5_in), |
.pciu_ta0_in (pciu_ta0_in), |
.pciu_ta1_in (pciu_ta1_in), |
.pciu_ta2_in (pciu_ta2_in), |
.pciu_ta3_in (pciu_ta3_in), |
.pciu_ta4_in (pciu_ta4_in), |
.pciu_ta5_in (pciu_ta5_in), |
.pciu_at_en_in (pciu_at_en_in), |
.pciu_cache_line_size_in (pciu_cache_line_size_in), |
.pciu_cache_lsize_not_zero_in (pciu_cache_lsize_not_zero_in), |
.pciu_pciif_frame_in (pciu_pciif_frame_in), |
.pciu_pciif_irdy_in (pciu_pciif_irdy_in), |
.pciu_pciif_idsel_in (pciu_pciif_idsel_in), |
.pciu_pciif_frame_reg_in (pciu_pciif_frame_reg_in), |
.pciu_pciif_irdy_reg_in (pciu_pciif_irdy_reg_in), |
.pciu_pciif_idsel_reg_in (pciu_pciif_idsel_reg_in), |
.pciu_pciif_ad_reg_in (pciu_pciif_ad_reg_in), |
.pciu_pciif_cbe_reg_in (pciu_pciif_cbe_reg_in), |
.pciu_pciif_cbe_in (pciu_pciif_cbe_in), |
.pciu_pciif_bckp_trdy_en_in (pciu_pciif_bckp_trdy_en_in), |
.pciu_pciif_bckp_devsel_in (pciu_pciif_bckp_devsel_in), |
.pciu_pciif_bckp_trdy_in (pciu_pciif_bckp_trdy_in), |
.pciu_pciif_bckp_stop_in (pciu_pciif_bckp_stop_in), |
.pciu_pciif_trdy_reg_in (pciu_pciif_trdy_reg_in), |
.pciu_pciif_stop_reg_in (pciu_pciif_stop_reg_in), |
.pciu_pciif_trdy_out (pciu_pciif_trdy_out), |
.pciu_pciif_stop_out (pciu_pciif_stop_out), |
.pciu_pciif_devsel_out (pciu_pciif_devsel_out), |
.pciu_pciif_trdy_en_out (pciu_pciif_trdy_en_out), |
.pciu_pciif_stop_en_out (pciu_pciif_stop_en_out), |
.pciu_pciif_devsel_en_out (pciu_pciif_devsel_en_out), |
.pciu_ad_load_out (pciu_ad_load_out), |
.pciu_ad_load_on_transfer_out (pciu_ad_load_on_transfer_out), |
.pciu_pciif_ad_out (pciu_pciif_ad_out), |
.pciu_pciif_ad_en_out (pciu_pciif_ad_en_out), |
.pciu_pciif_tabort_set_out (pciu_pciif_tabort_set_out), |
.pciu_err_addr_out (pciu_err_addr_out), |
.pciu_err_bc_out (pciu_err_bc_out), |
.pciu_err_data_out (pciu_err_data_out), |
.pciu_err_be_out (pciu_err_be_out), |
.pciu_err_signal_out (pciu_err_signal_out), |
.pciu_err_source_out (pciu_err_source_out), |
.pciu_err_rty_exp_out (pciu_err_rty_exp_out), |
.pciu_conf_offset_out (pciu_conf_offset_out), |
.pciu_conf_renable_out (pciu_conf_renable_out), |
.pciu_conf_wenable_out (pciu_conf_wenable_out), |
.pciu_conf_be_out (pciu_conf_be_out), |
.pciu_conf_data_out (pciu_conf_data_out), |
.pciu_conf_select_out (pciu_conf_select_out), |
.pciu_pci_drcomp_pending_out (pciu_pci_drcomp_pending_out), |
.pciu_pciw_fifo_empty_out (pciu_pciw_fifo_empty_out) |
|
`ifdef PCI_BIST |
, |
.mbist_si_i (mbist_so_o_internal), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
); |
|
|
// CONFIGURATION SPACE INPUTS |
`ifdef HOST |
|
wire [11:0] conf_w_addr_in = wbu_conf_offset_out ; |
wire [31:0] conf_w_data_in = wbu_conf_data_out ; |
wire conf_w_we_in = wbu_conf_wenable_out ; |
wire conf_w_re_in = wbu_conf_renable_out ; |
wire [3:0] conf_w_be_in = wbu_conf_be_out ; |
wire conf_w_clock = wb_clk ; |
wire [11:0] conf_r_addr_in = pciu_conf_offset_out ; |
wire conf_r_re_in = pciu_conf_renable_out ; |
|
`else |
`ifdef GUEST |
|
wire [11:0] conf_r_addr_in = wbu_conf_offset_out ; |
wire conf_r_re_in = wbu_conf_renable_out ; |
wire conf_w_clock = pci_clk ; |
wire [11:0] conf_w_addr_in = pciu_conf_offset_out ; |
wire [31:0] conf_w_data_in = pciu_conf_data_out ; |
wire conf_w_we_in = pciu_conf_wenable_out ; |
wire conf_w_re_in = pciu_conf_renable_out ; |
wire [3:0] conf_w_be_in = pciu_conf_be_out ; |
|
`endif |
`endif |
|
|
wire conf_perr_in = parchk_par_err_detect_out ; |
wire conf_serr_in = parchk_sig_serr_out ; |
wire conf_master_abort_recv_in = wbu_mabort_rec_out ; |
wire conf_target_abort_recv_in = wbu_tabort_rec_out ; |
wire conf_target_abort_set_in = pciu_pciif_tabort_set_out ; |
|
wire conf_master_data_par_err_in = parchk_perr_mas_detect_out ; |
|
wire [3:0] conf_pci_err_be_in = pciu_err_be_out ; |
wire [3:0] conf_pci_err_bc_in = pciu_err_bc_out; |
wire conf_pci_err_es_in = pciu_err_source_out ; |
wire conf_pci_err_rty_exp_in = pciu_err_rty_exp_out ; |
wire conf_pci_err_sig_in = pciu_err_signal_out ; |
wire [31:0] conf_pci_err_addr_in = pciu_err_addr_out ; |
wire [31:0] conf_pci_err_data_in = pciu_err_data_out ; |
|
wire [3:0] conf_wb_err_be_in = out_bckp_cbe_out ; |
wire [3:0] conf_wb_err_bc_in = wbu_err_bc_out ; |
wire conf_wb_err_rty_exp_in = wbu_err_rty_exp_out ; |
wire conf_wb_err_es_in = wbu_err_source_out ; |
wire conf_wb_err_sig_in = wbu_err_signal_out ; |
wire [31:0] conf_wb_err_addr_in = wbu_err_addr_out ; |
wire [31:0] conf_wb_err_data_in = out_bckp_ad_out ; |
|
wire conf_isr_int_prop_in = pci_into_conf_isr_int_prop_out ; |
wire conf_par_err_int_in = parchk_perr_mas_detect_out ; |
wire conf_sys_err_int_in = parchk_sig_serr_out ; |
|
pci_conf_space configuration( |
.reset (reset), |
.pci_clk (pci_clk), |
.wb_clk (wb_clk), |
.w_conf_address_in (conf_w_addr_in), |
.w_conf_data_in (conf_w_data_in), |
.w_conf_data_out (conf_w_data_out), |
.r_conf_address_in (conf_r_addr_in), |
.r_conf_data_out (conf_r_data_out), |
.w_we (conf_w_we_in), |
.w_re (conf_w_re_in), |
.r_re (conf_r_re_in), |
.w_byte_en (conf_w_be_in), |
.w_clock (conf_w_clock), |
.serr_enable (conf_serr_enable_out), |
.perr_response (conf_perr_response_out), |
.pci_master_enable (conf_pci_master_enable_out), |
.memory_space_enable (conf_mem_space_enable_out), |
.io_space_enable (conf_io_space_enable_out), |
.perr_in (conf_perr_in), |
.serr_in (conf_serr_in), |
.master_abort_recv (conf_master_abort_recv_in), |
.target_abort_recv (conf_target_abort_recv_in), |
.target_abort_set (conf_target_abort_set_in), |
.master_data_par_err (conf_master_data_par_err_in), |
.cache_line_size_to_pci (conf_cache_line_size_to_pci_out), |
.cache_line_size_to_wb (conf_cache_line_size_to_wb_out), |
.cache_lsize_not_zero_to_wb (conf_cache_lsize_not_zero_to_wb_out), |
.latency_tim (conf_latency_tim_out), |
.pci_base_addr0 (conf_pci_ba0_out), |
.pci_base_addr1 (conf_pci_ba1_out), |
.pci_base_addr2 (conf_pci_ba2_out), |
.pci_base_addr3 (conf_pci_ba3_out), |
.pci_base_addr4 (conf_pci_ba4_out), |
.pci_base_addr5 (conf_pci_ba5_out), |
.pci_memory_io0 (conf_pci_mem_io0_out), |
.pci_memory_io1 (conf_pci_mem_io1_out), |
.pci_memory_io2 (conf_pci_mem_io2_out), |
.pci_memory_io3 (conf_pci_mem_io3_out), |
.pci_memory_io4 (conf_pci_mem_io4_out), |
.pci_memory_io5 (conf_pci_mem_io5_out), |
.pci_addr_mask0 (conf_pci_am0_out), |
.pci_addr_mask1 (conf_pci_am1_out), |
.pci_addr_mask2 (conf_pci_am2_out), |
.pci_addr_mask3 (conf_pci_am3_out), |
.pci_addr_mask4 (conf_pci_am4_out), |
.pci_addr_mask5 (conf_pci_am5_out), |
.pci_tran_addr0 (conf_pci_ta0_out), |
.pci_tran_addr1 (conf_pci_ta1_out), |
.pci_tran_addr2 (conf_pci_ta2_out), |
.pci_tran_addr3 (conf_pci_ta3_out), |
.pci_tran_addr4 (conf_pci_ta4_out), |
.pci_tran_addr5 (conf_pci_ta5_out), |
.pci_img_ctrl0 (conf_pci_img_ctrl0_out), |
.pci_img_ctrl1 (conf_pci_img_ctrl1_out), |
.pci_img_ctrl2 (conf_pci_img_ctrl2_out), |
.pci_img_ctrl3 (conf_pci_img_ctrl3_out), |
.pci_img_ctrl4 (conf_pci_img_ctrl4_out), |
.pci_img_ctrl5 (conf_pci_img_ctrl5_out), |
.pci_error_be (conf_pci_err_be_in), |
.pci_error_bc (conf_pci_err_bc_in), |
.pci_error_rty_exp (conf_pci_err_rty_exp_in), |
.pci_error_es (conf_pci_err_es_in), |
.pci_error_sig (conf_pci_err_sig_in), |
.pci_error_addr (conf_pci_err_addr_in), |
.pci_error_data (conf_pci_err_data_in), |
.wb_base_addr0 (conf_wb_ba0_out), |
.wb_base_addr1 (conf_wb_ba1_out), |
.wb_base_addr2 (conf_wb_ba2_out), |
.wb_base_addr3 (conf_wb_ba3_out), |
.wb_base_addr4 (conf_wb_ba4_out), |
.wb_base_addr5 (conf_wb_ba5_out), |
.wb_memory_io0 (conf_wb_mem_io0_out), |
.wb_memory_io1 (conf_wb_mem_io1_out), |
.wb_memory_io2 (conf_wb_mem_io2_out), |
.wb_memory_io3 (conf_wb_mem_io3_out), |
.wb_memory_io4 (conf_wb_mem_io4_out), |
.wb_memory_io5 (conf_wb_mem_io5_out), |
.wb_addr_mask0 (conf_wb_am0_out), |
.wb_addr_mask1 (conf_wb_am1_out), |
.wb_addr_mask2 (conf_wb_am2_out), |
.wb_addr_mask3 (conf_wb_am3_out), |
.wb_addr_mask4 (conf_wb_am4_out), |
.wb_addr_mask5 (conf_wb_am5_out), |
.wb_tran_addr0 (conf_wb_ta0_out), |
.wb_tran_addr1 (conf_wb_ta1_out), |
.wb_tran_addr2 (conf_wb_ta2_out), |
.wb_tran_addr3 (conf_wb_ta3_out), |
.wb_tran_addr4 (conf_wb_ta4_out), |
.wb_tran_addr5 (conf_wb_ta5_out), |
.wb_img_ctrl0 (conf_wb_img_ctrl0_out), |
.wb_img_ctrl1 (conf_wb_img_ctrl1_out), |
.wb_img_ctrl2 (conf_wb_img_ctrl2_out), |
.wb_img_ctrl3 (conf_wb_img_ctrl3_out), |
.wb_img_ctrl4 (conf_wb_img_ctrl4_out), |
.wb_img_ctrl5 (conf_wb_img_ctrl5_out), |
.wb_error_be (conf_wb_err_be_in), |
.wb_error_bc (conf_wb_err_bc_in), |
.wb_error_rty_exp (conf_wb_err_rty_exp_in), |
.wb_error_es (conf_wb_err_es_in), |
.wb_error_sig (conf_wb_err_sig_in), |
.wb_error_addr (conf_wb_err_addr_in), |
.wb_error_data (conf_wb_err_data_in), |
.config_addr (conf_ccyc_addr_out), |
.icr_soft_res (conf_soft_res_out), |
.int_out (conf_int_out), |
.isr_int_prop (conf_isr_int_prop_in), |
.isr_par_err_int (conf_par_err_int_in), |
.isr_sys_err_int (conf_sys_err_int_in) |
) ; |
|
// pci data io multiplexer inputs |
wire pci_mux_tar_ad_en_in = pciu_pciif_ad_en_out ; |
wire pci_mux_tar_ad_en_reg_in = out_bckp_tar_ad_en_out ; |
wire [31:0] pci_mux_tar_ad_in = pciu_pciif_ad_out ; |
wire pci_mux_devsel_in = pciu_pciif_devsel_out ; |
wire pci_mux_devsel_en_in = pciu_pciif_devsel_en_out ; |
wire pci_mux_trdy_in = pciu_pciif_trdy_out ; |
wire pci_mux_trdy_en_in = pciu_pciif_trdy_en_out ; |
wire pci_mux_stop_in = pciu_pciif_stop_out ; |
wire pci_mux_stop_en_in = pciu_pciif_stop_en_out ; |
wire pci_mux_tar_load_in = pciu_ad_load_out ; |
wire pci_mux_tar_load_on_transfer_in = pciu_ad_load_on_transfer_out ; |
|
wire pci_mux_mas_ad_en_in = wbu_pciif_ad_en_out ; |
wire [31:0] pci_mux_mas_ad_in = wbu_pciif_ad_out ; |
|
wire pci_mux_frame_in = wbu_pciif_frame_out ; |
wire pci_mux_frame_en_in = wbu_pciif_frame_en_out ; |
wire pci_mux_irdy_in = wbu_pciif_irdy_out; |
wire pci_mux_irdy_en_in = wbu_pciif_irdy_en_out; |
wire pci_mux_mas_load_in = wbu_ad_load_out ; |
wire pci_mux_mas_load_on_transfer_in = wbu_ad_load_on_transfer_out ; |
wire [3:0] pci_mux_cbe_in = wbu_pciif_cbe_out ; |
wire pci_mux_cbe_en_in = wbu_pciif_cbe_en_out ; |
|
wire pci_mux_par_in = parchk_pci_par_out ; |
wire pci_mux_par_en_in = parchk_pci_par_en_out ; |
wire pci_mux_perr_in = parchk_pci_perr_out ; |
wire pci_mux_perr_en_in = parchk_pci_perr_en_out ; |
wire pci_mux_serr_in = parchk_pci_serr_out ; |
wire pci_mux_serr_en_in = parchk_pci_serr_en_out; |
|
wire pci_mux_req_in = wbu_pciif_req_out ; |
wire pci_mux_frame_load_in = wbu_pciif_frame_load_out ; |
|
wire pci_mux_pci_irdy_in = pci_irdy_i ; |
wire pci_mux_pci_trdy_in = pci_trdy_i ; |
wire pci_mux_pci_frame_in = pci_frame_i ; |
wire pci_mux_pci_stop_in = pci_stop_i ; |
|
pci_io_mux pci_io_mux |
( |
.reset_in (reset), |
.clk_in (pci_clk), |
.frame_in (pci_mux_frame_in), |
.frame_en_in (pci_mux_frame_en_in), |
.frame_load_in (pci_mux_frame_load_in), |
.irdy_in (pci_mux_irdy_in), |
.irdy_en_in (pci_mux_irdy_en_in), |
.devsel_in (pci_mux_devsel_in), |
.devsel_en_in (pci_mux_devsel_en_in), |
.trdy_in (pci_mux_trdy_in), |
.trdy_en_in (pci_mux_trdy_en_in), |
.stop_in (pci_mux_stop_in), |
.stop_en_in (pci_mux_stop_en_in), |
.master_load_in (pci_mux_mas_load_in), |
.master_load_on_transfer_in (pci_mux_mas_load_on_transfer_in), |
.target_load_in (pci_mux_tar_load_in), |
.target_load_on_transfer_in (pci_mux_tar_load_on_transfer_in), |
.cbe_in (pci_mux_cbe_in), |
.cbe_en_in (pci_mux_cbe_en_in), |
.mas_ad_in (pci_mux_mas_ad_in), |
.tar_ad_in (pci_mux_tar_ad_in), |
|
.mas_ad_en_in (pci_mux_mas_ad_en_in), |
.tar_ad_en_in (pci_mux_tar_ad_en_in), |
.tar_ad_en_reg_in (pci_mux_tar_ad_en_reg_in), |
|
.par_in (pci_mux_par_in), |
.par_en_in (pci_mux_par_en_in), |
.perr_in (pci_mux_perr_in), |
.perr_en_in (pci_mux_perr_en_in), |
.serr_in (pci_mux_serr_in), |
.serr_en_in (pci_mux_serr_en_in), |
|
.frame_en_out (pci_mux_frame_en_out), |
.irdy_en_out (pci_mux_irdy_en_out), |
.devsel_en_out (pci_mux_devsel_en_out), |
.trdy_en_out (pci_mux_trdy_en_out), |
.stop_en_out (pci_mux_stop_en_out), |
.cbe_en_out (pci_mux_cbe_en_out), |
.ad_en_out (pci_mux_ad_en_out), |
|
.frame_out (pci_mux_frame_out), |
.irdy_out (pci_mux_irdy_out), |
.devsel_out (pci_mux_devsel_out), |
.trdy_out (pci_mux_trdy_out), |
.stop_out (pci_mux_stop_out), |
.cbe_out (pci_mux_cbe_out), |
.ad_out (pci_mux_ad_out), |
.ad_load_out (pci_mux_ad_load_out), |
|
.par_out (pci_mux_par_out), |
.par_en_out (pci_mux_par_en_out), |
.perr_out (pci_mux_perr_out), |
.perr_en_out (pci_mux_perr_en_out), |
.serr_out (pci_mux_serr_out), |
.serr_en_out (pci_mux_serr_en_out), |
.req_in (pci_mux_req_in), |
.req_out (pci_mux_req_out), |
.req_en_out (pci_mux_req_en_out), |
.pci_irdy_in (pci_mux_pci_irdy_in), |
.pci_trdy_in (pci_mux_pci_trdy_in), |
.pci_frame_in (pci_mux_pci_frame_in), |
.pci_stop_in (pci_mux_pci_stop_in), |
.ad_en_unregistered_out (pci_mux_ad_en_unregistered_out) |
); |
|
pci_cur_out_reg output_backup |
( |
.reset_in (reset), |
.clk_in (pci_clk), |
.frame_in (pci_mux_frame_in), |
.frame_en_in (pci_mux_frame_en_in), |
.frame_load_in (pci_mux_frame_load_in), |
.irdy_in (pci_mux_irdy_in), |
.irdy_en_in (pci_mux_irdy_en_in), |
.devsel_in (pci_mux_devsel_in), |
.trdy_in (pci_mux_trdy_in), |
.trdy_en_in (pci_mux_trdy_en_in), |
.stop_in (pci_mux_stop_in), |
.ad_load_in (pci_mux_ad_load_out), |
.cbe_in (pci_mux_cbe_in), |
.cbe_en_in (pci_mux_cbe_en_in), |
.mas_ad_in (pci_mux_mas_ad_in), |
.tar_ad_in (pci_mux_tar_ad_in), |
|
.mas_ad_en_in (pci_mux_mas_ad_en_in), |
.tar_ad_en_in (pci_mux_tar_ad_en_in), |
.ad_en_unregistered_in (pci_mux_ad_en_unregistered_out), |
|
.par_in (pci_mux_par_in), |
.par_en_in (pci_mux_par_en_in), |
.perr_in (pci_mux_perr_in), |
.perr_en_in (pci_mux_perr_en_in), |
.serr_in (pci_mux_serr_in), |
.serr_en_in (pci_mux_serr_en_in), |
|
.frame_out (out_bckp_frame_out), |
.frame_en_out (out_bckp_frame_en_out), |
.irdy_out (out_bckp_irdy_out), |
.irdy_en_out (out_bckp_irdy_en_out), |
.devsel_out (out_bckp_devsel_out), |
.trdy_out (out_bckp_trdy_out), |
.trdy_en_out (out_bckp_trdy_en_out), |
.stop_out (out_bckp_stop_out), |
.cbe_out (out_bckp_cbe_out), |
.ad_out (out_bckp_ad_out), |
.ad_en_out (out_bckp_ad_en_out), |
.cbe_en_out (out_bckp_cbe_en_out), |
.tar_ad_en_out (out_bckp_tar_ad_en_out), |
.mas_ad_en_out (out_bckp_mas_ad_en_out), |
|
.par_out (out_bckp_par_out), |
.par_en_out (out_bckp_par_en_out), |
.perr_out (out_bckp_perr_out), |
.perr_en_out (out_bckp_perr_en_out), |
.serr_out (out_bckp_serr_out), |
.serr_en_out (out_bckp_serr_en_out) |
) ; |
|
// PARITY CHECKER INPUTS |
wire parchk_pci_par_in = pci_par_i ; |
wire parchk_pci_perr_in = pci_perr_i ; |
wire parchk_pci_frame_reg_in = in_reg_frame_out ; |
wire parchk_pci_frame_en_in = out_bckp_frame_en_out ; |
wire parchk_pci_irdy_en_in = out_bckp_irdy_en_out ; |
wire parchk_pci_irdy_reg_in = in_reg_irdy_out ; |
wire parchk_pci_trdy_reg_in = in_reg_trdy_out ; |
|
|
wire parchk_pci_trdy_en_in = out_bckp_trdy_en_out ; |
|
|
wire [31:0] parchk_pci_ad_out_in = out_bckp_ad_out ; |
wire [31:0] parchk_pci_ad_reg_in = in_reg_ad_out ; |
wire [3:0] parchk_pci_cbe_in_in = pci_cbe_i ; |
wire [3:0] parchk_pci_cbe_reg_in = in_reg_cbe_out ; |
wire [3:0] parchk_pci_cbe_out_in = out_bckp_cbe_out ; |
wire parchk_pci_ad_en_in = out_bckp_ad_en_out ; |
wire parchk_par_err_response_in = conf_perr_response_out ; |
wire parchk_serr_enable_in = conf_serr_enable_out ; |
|
wire parchk_pci_perr_out_in = out_bckp_perr_out ; |
wire parchk_pci_serr_en_in = out_bckp_serr_en_out ; |
wire parchk_pci_serr_out_in = out_bckp_serr_out ; |
wire parchk_pci_cbe_en_in = out_bckp_cbe_en_out ; |
|
wire parchk_pci_par_en_in = out_bckp_par_en_out ; |
|
pci_parity_check parity_checker |
( |
.reset_in (reset), |
.clk_in (pci_clk), |
.pci_par_in (parchk_pci_par_in), |
.pci_par_out (parchk_pci_par_out), |
.pci_par_en_out (parchk_pci_par_en_out), |
.pci_par_en_in (parchk_pci_par_en_in), |
.pci_perr_in (parchk_pci_perr_in), |
.pci_perr_out (parchk_pci_perr_out), |
.pci_perr_en_out (parchk_pci_perr_en_out), |
.pci_perr_out_in (parchk_pci_perr_out_in), |
.pci_serr_out (parchk_pci_serr_out), |
.pci_serr_out_in (parchk_pci_serr_out_in), |
.pci_serr_en_out (parchk_pci_serr_en_out), |
.pci_serr_en_in (parchk_pci_serr_en_in), |
.pci_frame_reg_in (parchk_pci_frame_reg_in), |
.pci_frame_en_in (parchk_pci_frame_en_in), |
.pci_irdy_en_in (parchk_pci_irdy_en_in), |
.pci_irdy_reg_in (parchk_pci_irdy_reg_in), |
.pci_trdy_reg_in (parchk_pci_trdy_reg_in), |
.pci_trdy_en_in (parchk_pci_trdy_en_in), |
.pci_ad_out_in (parchk_pci_ad_out_in), |
.pci_ad_reg_in (parchk_pci_ad_reg_in), |
.pci_cbe_in_in (parchk_pci_cbe_in_in), |
.pci_cbe_reg_in (parchk_pci_cbe_reg_in), |
.pci_cbe_en_in (parchk_pci_cbe_en_in), |
.pci_cbe_out_in (parchk_pci_cbe_out_in), |
.pci_ad_en_in (parchk_pci_ad_en_in), |
.par_err_response_in (parchk_par_err_response_in), |
.par_err_detect_out (parchk_par_err_detect_out), |
.perr_mas_detect_out (parchk_perr_mas_detect_out), |
.serr_enable_in (parchk_serr_enable_in), |
.sig_serr_out (parchk_sig_serr_out) |
); |
|
wire in_reg_gnt_in = pci_gnt_i ; |
wire in_reg_frame_in = pci_frame_i ; |
wire in_reg_irdy_in = pci_irdy_i ; |
wire in_reg_trdy_in = pci_trdy_i ; |
wire in_reg_stop_in = pci_stop_i ; |
wire in_reg_devsel_in = pci_devsel_i ; |
wire in_reg_idsel_in = pci_idsel_i ; |
wire [31:0] in_reg_ad_in = pci_ad_i ; |
wire [3:0] in_reg_cbe_in = pci_cbe_i ; |
|
pci_in_reg input_register |
( |
.reset_in (reset), |
.clk_in (pci_clk), |
|
.pci_gnt_in (in_reg_gnt_in), |
.pci_frame_in (in_reg_frame_in), |
.pci_irdy_in (in_reg_irdy_in), |
.pci_trdy_in (in_reg_trdy_in), |
.pci_stop_in (in_reg_stop_in), |
.pci_devsel_in (in_reg_devsel_in), |
.pci_idsel_in (in_reg_idsel_in), |
.pci_ad_in (in_reg_ad_in), |
.pci_cbe_in (in_reg_cbe_in), |
|
.pci_gnt_reg_out (in_reg_gnt_out), |
.pci_frame_reg_out (in_reg_frame_out), |
.pci_irdy_reg_out (in_reg_irdy_out), |
.pci_trdy_reg_out (in_reg_trdy_out), |
.pci_stop_reg_out (in_reg_stop_out), |
.pci_devsel_reg_out (in_reg_devsel_out), |
.pci_idsel_reg_out (in_reg_idsel_out), |
.pci_ad_reg_out (in_reg_ad_out), |
.pci_cbe_reg_out (in_reg_cbe_out) |
); |
|
endmodule |
/verilog/pci_wb_slave_unit.v
0,0 → 1,866
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "wb_slave_unit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.8 2002/10/18 03:36:37 tadejm |
// Changed wrong signal name mbist_sen into mbist_ctrl_i. |
// |
// Revision 1.7 2002/10/17 22:49:22 tadejm |
// Changed BIST signals for RAMs. |
// |
// Revision 1.6 2002/10/11 10:09:01 mihad |
// Added additional testcase and changed rst name in BIST to trst |
// |
// Revision 1.5 2002/10/08 17:17:06 mihad |
// Added BIST signals for RAMs. |
// |
// Revision 1.4 2002/09/25 15:53:52 mihad |
// Removed all logic from asynchronous reset network |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// Module instantiates and connects other modules lower in hierarcy |
// Wishbone slave unit consists of modules that together form datapath |
// between external WISHBONE masters and external PCI targets |
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_wb_slave_unit |
( |
reset_in, |
wb_clock_in, |
pci_clock_in, |
ADDR_I, |
SDATA_I, |
SDATA_O, |
CYC_I, |
STB_I, |
WE_I, |
SEL_I, |
ACK_O, |
RTY_O, |
ERR_O, |
CAB_I, |
wbu_map_in, |
wbu_pref_en_in, |
wbu_mrl_en_in, |
wbu_pci_drcomp_pending_in, |
wbu_conf_data_in, |
wbu_pciw_empty_in, |
wbu_bar0_in, |
wbu_bar1_in, |
wbu_bar2_in, |
wbu_bar3_in, |
wbu_bar4_in, |
wbu_bar5_in, |
wbu_am0_in, |
wbu_am1_in, |
wbu_am2_in, |
wbu_am3_in, |
wbu_am4_in, |
wbu_am5_in, |
wbu_ta0_in, |
wbu_ta1_in, |
wbu_ta2_in, |
wbu_ta3_in, |
wbu_ta4_in, |
wbu_ta5_in, |
wbu_at_en_in, |
wbu_ccyc_addr_in , |
wbu_master_enable_in, |
wbu_cache_line_size_not_zero, |
wbu_cache_line_size_in, |
wbu_pciif_gnt_in, |
wbu_pciif_frame_in, |
wbu_pciif_irdy_in, |
wbu_pciif_trdy_in, |
wbu_pciif_trdy_reg_in, |
wbu_pciif_stop_in, |
wbu_pciif_stop_reg_in, |
wbu_pciif_devsel_in, |
wbu_pciif_devsel_reg_in, |
wbu_pciif_ad_reg_in, |
wbu_pciif_req_out, |
wbu_pciif_frame_out, |
wbu_pciif_frame_en_out, |
wbu_pciif_frame_en_in, |
wbu_pciif_frame_out_in, |
wbu_pciif_frame_load_out, |
wbu_pciif_irdy_out, |
wbu_pciif_irdy_en_out, |
wbu_pciif_ad_out, |
wbu_pciif_ad_en_out, |
wbu_pciif_cbe_out, |
wbu_pciif_cbe_en_out, |
wbu_err_addr_out, |
wbu_err_bc_out, |
wbu_err_signal_out, |
wbu_err_source_out, |
wbu_err_rty_exp_out, |
wbu_tabort_rec_out, |
wbu_mabort_rec_out, |
wbu_conf_offset_out, |
wbu_conf_renable_out, |
wbu_conf_wenable_out, |
wbu_conf_be_out, |
wbu_conf_data_out, |
wbu_del_read_comp_pending_out, |
wbu_wbw_fifo_empty_out, |
wbu_latency_tim_val_in, |
wbu_ad_load_out, |
wbu_ad_load_on_transfer_out |
|
`ifdef PCI_BIST |
, |
// debug chain signals |
mbist_si_i, // bist scan serial in |
mbist_so_o, // bist scan serial out |
mbist_ctrl_i // bist chain shift control |
`endif |
); |
|
input reset_in, |
wb_clock_in, |
pci_clock_in ; |
|
input [31:0] ADDR_I ; |
input [31:0] SDATA_I ; |
output [31:0] SDATA_O ; |
input CYC_I ; |
input STB_I ; |
input WE_I ; |
input [3:0] SEL_I ; |
output ACK_O ; |
output RTY_O ; |
output ERR_O ; |
input CAB_I ; |
|
input [5:0] wbu_map_in ; |
input [5:0] wbu_pref_en_in ; |
input [5:0] wbu_mrl_en_in ; |
|
input wbu_pci_drcomp_pending_in ; |
|
input [31:0] wbu_conf_data_in ; |
|
input wbu_pciw_empty_in ; |
|
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar0_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar1_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar2_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar3_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar4_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar5_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am0_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am1_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am2_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am3_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am4_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am5_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta0_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta1_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta2_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta3_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta4_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta5_in ; |
input [5:0] wbu_at_en_in ; |
|
input [23:0] wbu_ccyc_addr_in ; |
|
input wbu_master_enable_in ; |
|
input wbu_cache_line_size_not_zero ; |
input [7:0] wbu_cache_line_size_in ; |
|
input wbu_pciif_gnt_in ; |
input wbu_pciif_frame_in ; |
input wbu_pciif_frame_en_in ; |
input wbu_pciif_irdy_in ; |
input wbu_pciif_trdy_in; |
input wbu_pciif_trdy_reg_in; |
input wbu_pciif_stop_in ; |
input wbu_pciif_stop_reg_in ; |
input wbu_pciif_devsel_in ; |
input wbu_pciif_devsel_reg_in ; |
input [31:0] wbu_pciif_ad_reg_in ; |
|
output wbu_pciif_req_out ; |
output wbu_pciif_frame_out ; |
output wbu_pciif_frame_en_out ; |
input wbu_pciif_frame_out_in ; |
output wbu_pciif_frame_load_out ; |
output wbu_pciif_irdy_out ; |
output wbu_pciif_irdy_en_out ; |
output [31:0] wbu_pciif_ad_out ; |
output wbu_pciif_ad_en_out ; |
output [3:0] wbu_pciif_cbe_out ; |
output wbu_pciif_cbe_en_out ; |
|
output [31:0] wbu_err_addr_out ; |
output [3:0] wbu_err_bc_out ; |
output wbu_err_signal_out ; |
output wbu_err_source_out ; |
output wbu_err_rty_exp_out ; |
output wbu_tabort_rec_out ; |
output wbu_mabort_rec_out ; |
|
output [11:0] wbu_conf_offset_out ; |
output wbu_conf_renable_out ; |
output wbu_conf_wenable_out ; |
output [3:0] wbu_conf_be_out ; |
output [31:0] wbu_conf_data_out ; |
|
output wbu_del_read_comp_pending_out ; |
output wbu_wbw_fifo_empty_out ; |
|
input [7:0] wbu_latency_tim_val_in ; |
|
output wbu_ad_load_out ; |
output wbu_ad_load_on_transfer_out ; |
|
`ifdef PCI_BIST |
/*----------------------------------------------------- |
BIST debug chain port signals |
-----------------------------------------------------*/ |
input mbist_si_i; // bist scan serial in |
output mbist_so_o; // bist scan serial out |
input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control |
`endif |
|
// pci master interface outputs |
wire [31:0] pcim_if_address_out ; |
wire [3:0] pcim_if_bc_out ; |
wire [31:0] pcim_if_data_out ; |
wire [3:0] pcim_if_be_out ; |
wire pcim_if_req_out ; |
wire pcim_if_rdy_out ; |
wire pcim_if_last_out ; |
wire pcim_if_wbw_renable_out ; |
wire pcim_if_wbr_wenable_out ; |
wire [31:0] pcim_if_wbr_data_out ; |
wire [3:0] pcim_if_wbr_be_out ; |
wire [3:0] pcim_if_wbr_control_out ; |
wire pcim_if_del_complete_out ; |
wire pcim_if_del_error_out ; |
wire pcim_if_del_rty_exp_out ; |
wire [31:0] pcim_if_err_addr_out ; |
wire [3:0] pcim_if_err_bc_out ; |
wire pcim_if_err_signal_out ; |
wire pcim_if_err_source_out ; |
wire pcim_if_err_rty_exp_out ; |
wire pcim_if_tabort_out ; |
wire pcim_if_mabort_out ; |
wire [31:0] pcim_if_next_data_out ; |
wire [3:0] pcim_if_next_be_out ; |
wire pcim_if_next_last_out ; |
wire pcim_if_posted_write_not_present_out ; |
|
|
|
wire pcim_sm_req_out ; |
wire pcim_sm_frame_out ; |
wire pcim_sm_frame_en_out ; |
wire pcim_sm_irdy_out ; |
wire pcim_sm_irdy_en_out ; |
wire [31:0] pcim_sm_ad_out ; |
wire pcim_sm_ad_en_out ; |
wire [3:0] pcim_sm_cbe_out ; |
wire pcim_sm_cbe_en_out ; |
wire pcim_sm_ad_load_out ; |
wire pcim_sm_ad_load_on_transfer_out ; |
|
wire pcim_sm_wait_out ; |
wire pcim_sm_wtransfer_out ; |
wire pcim_sm_rtransfer_out ; |
wire pcim_sm_retry_out ; |
wire pcim_sm_rerror_out ; |
wire pcim_sm_first_out ; |
wire pcim_sm_mabort_out ; |
wire pcim_sm_frame_load_out ; |
|
assign wbu_pciif_frame_load_out = pcim_sm_frame_load_out ; |
|
assign wbu_err_addr_out = pcim_if_err_addr_out ; |
assign wbu_err_bc_out = pcim_if_err_bc_out ; |
assign wbu_err_signal_out = pcim_if_err_signal_out ; |
assign wbu_err_source_out = pcim_if_err_source_out ; |
assign wbu_err_rty_exp_out = pcim_if_err_rty_exp_out ; |
assign wbu_tabort_rec_out = pcim_if_tabort_out ; |
assign wbu_mabort_rec_out = pcim_if_mabort_out ; |
|
assign wbu_wbw_fifo_empty_out = pcim_if_posted_write_not_present_out ; |
|
// pci master state machine outputs |
// pci interface signals |
assign wbu_pciif_req_out = pcim_sm_req_out ; |
assign wbu_pciif_frame_out = pcim_sm_frame_out ; |
assign wbu_pciif_frame_en_out = pcim_sm_frame_en_out ; |
assign wbu_pciif_irdy_out = pcim_sm_irdy_out ; |
assign wbu_pciif_irdy_en_out = pcim_sm_irdy_en_out ; |
assign wbu_pciif_ad_out = pcim_sm_ad_out ; |
assign wbu_pciif_ad_en_out = pcim_sm_ad_en_out ; |
assign wbu_pciif_cbe_out = pcim_sm_cbe_out ; |
assign wbu_pciif_cbe_en_out = pcim_sm_cbe_en_out ; |
assign wbu_ad_load_out = pcim_sm_ad_load_out ; |
assign wbu_ad_load_on_transfer_out = pcim_sm_ad_load_on_transfer_out ; |
|
// signals to internal of the core |
wire [31:0] pcim_sm_data_out ; |
|
// wishbone slave state machine outputs |
wire [3:0] wbs_sm_del_bc_out ; |
wire wbs_sm_del_req_out ; |
wire wbs_sm_del_done_out ; |
wire wbs_sm_del_burst_out ; |
wire wbs_sm_del_write_out ; |
wire [11:0] wbs_sm_conf_offset_out ; |
wire wbs_sm_conf_renable_out ; |
wire wbs_sm_conf_wenable_out ; |
wire [3:0] wbs_sm_conf_be_out ; |
wire [31:0] wbs_sm_conf_data_out ; |
wire [31:0] wbs_sm_data_out ; |
wire [3:0] wbs_sm_cbe_out ; |
wire wbs_sm_wbw_wenable_out ; |
wire [3:0] wbs_sm_wbw_control_out ; |
wire wbs_sm_wbr_renable_out ; |
wire wbs_sm_wbr_flush_out ; |
wire wbs_sm_del_in_progress_out ; |
wire [31:0] wbs_sm_sdata_out ; |
wire wbs_sm_ack_out ; |
wire wbs_sm_rty_out ; |
wire wbs_sm_err_out ; |
wire wbs_sm_sample_address_out ; |
|
assign wbu_conf_offset_out = wbs_sm_conf_offset_out ; |
assign wbu_conf_renable_out = wbs_sm_conf_renable_out ; |
assign wbu_conf_wenable_out = wbs_sm_conf_wenable_out ; |
assign wbu_conf_be_out = ~wbs_sm_conf_be_out ; |
assign wbu_conf_data_out = wbs_sm_conf_data_out ; |
|
assign SDATA_O = wbs_sm_sdata_out ; |
assign ACK_O = wbs_sm_ack_out ; |
assign RTY_O = wbs_sm_rty_out ; |
assign ERR_O = wbs_sm_err_out ; |
|
|
// wbw_wbr fifo outputs |
|
// wbw_fifo_outputs: |
wire [31:0] fifos_wbw_addr_data_out ; |
wire [3:0] fifos_wbw_cbe_out ; |
wire [3:0] fifos_wbw_control_out ; |
wire fifos_wbw_almost_full_out ; |
wire fifos_wbw_full_out ; |
wire fifos_wbw_empty_out ; |
wire fifos_wbw_transaction_ready_out ; |
|
// wbr_fifo_outputs |
wire [31:0] fifos_wbr_data_out ; |
wire [3:0] fifos_wbr_be_out ; |
wire [3:0] fifos_wbr_control_out ; |
wire fifos_wbr_empty_out ; |
|
// address multiplexer outputs |
wire [5:0] amux_hit_out ; |
wire [31:0] amux_address_out ; |
|
// delayed transaction logic outputs |
wire [31:0] del_sync_addr_out ; |
wire [3:0] del_sync_be_out ; |
wire del_sync_we_out ; |
wire del_sync_comp_req_pending_out ; |
wire del_sync_comp_comp_pending_out ; |
wire del_sync_req_req_pending_out ; |
wire del_sync_req_comp_pending_out ; |
wire [3:0] del_sync_bc_out ; |
wire del_sync_status_out ; |
wire del_sync_comp_flush_out ; |
wire del_sync_burst_out ; |
|
assign wbu_del_read_comp_pending_out = del_sync_comp_comp_pending_out ; |
|
// delayed write storage output |
wire [31:0] del_write_data_out ; |
|
// config. cycle address decoder output |
wire [31:0] ccyc_addr_out ; |
|
|
// WISHBONE slave interface inputs |
wire [4:0] wbs_sm_hit_in = amux_hit_out[5:1] ; |
wire wbs_sm_conf_hit_in = amux_hit_out[0] ; |
wire [4:0] wbs_sm_map_in = wbu_map_in[5:1] ; |
wire [4:0] wbs_sm_pref_en_in = wbu_pref_en_in[5:1] ; |
wire [4:0] wbs_sm_mrl_en_in = wbu_mrl_en_in[5:1] ; |
wire [31:0] wbs_sm_addr_in = amux_address_out ; |
wire [3:0] wbs_sm_del_bc_in = del_sync_bc_out ; |
wire wbs_sm_del_req_pending_in = del_sync_req_req_pending_out ; |
wire wbs_sm_wb_del_comp_pending_in = del_sync_req_comp_pending_out ; |
wire wbs_sm_pci_drcomp_pending_in = wbu_pci_drcomp_pending_in ; |
wire wbs_sm_del_write_in = del_sync_we_out ; |
wire wbs_sm_del_error_in = del_sync_status_out ; |
wire [31:0] wbs_sm_del_addr_in = del_sync_addr_out ; |
wire [3:0] wbs_sm_del_be_in = del_sync_be_out ; |
wire [31:0] wbs_sm_conf_data_in = wbu_conf_data_in ; |
wire wbs_sm_wbw_almost_full_in = fifos_wbw_almost_full_out ; |
wire wbs_sm_wbw_full_in = fifos_wbw_full_out ; |
wire [3:0] wbs_sm_wbr_be_in = fifos_wbr_be_out ; |
wire [31:0] wbs_sm_wbr_data_in = fifos_wbr_data_out ; |
wire [3:0] wbs_sm_wbr_control_in = fifos_wbr_control_out ; |
wire wbs_sm_wbr_empty_in = fifos_wbr_empty_out ; |
wire wbs_sm_pciw_empty_in = wbu_pciw_empty_in ; |
wire wbs_sm_lock_in = ~wbu_master_enable_in ; |
wire wbs_sm_cache_line_size_not_zero = wbu_cache_line_size_not_zero ; |
wire wbs_sm_cyc_in = CYC_I ; |
wire wbs_sm_stb_in = STB_I ; |
wire wbs_sm_we_in = WE_I ; |
wire [3:0] wbs_sm_sel_in = SEL_I ; |
wire [31:0] wbs_sm_sdata_in = SDATA_I ; |
wire wbs_sm_cab_in = CAB_I ; |
wire [31:0] wbs_sm_ccyc_addr_in = ccyc_addr_out ; |
|
// WISHBONE slave interface instantiation |
pci_wb_slave wishbone_slave( |
.wb_clock_in (wb_clock_in) , |
.reset_in (reset_in) , |
.wb_hit_in (wbs_sm_hit_in) , |
.wb_conf_hit_in (wbs_sm_conf_hit_in) , |
.wb_map_in (wbs_sm_map_in) , |
.wb_pref_en_in (wbs_sm_pref_en_in) , |
.wb_mrl_en_in (wbs_sm_mrl_en_in) , |
.wb_addr_in (wbs_sm_addr_in), |
.del_bc_in (wbs_sm_del_bc_in), |
.wb_del_req_pending_in (wbs_sm_del_req_pending_in), |
.wb_del_comp_pending_in (wbs_sm_wb_del_comp_pending_in), |
.pci_drcomp_pending_in (wbs_sm_pci_drcomp_pending_in), |
.del_bc_out (wbs_sm_del_bc_out), |
.del_req_out (wbs_sm_del_req_out), |
.del_done_out (wbs_sm_del_done_out), |
.del_burst_out (wbs_sm_del_burst_out), |
.del_write_out (wbs_sm_del_write_out), |
.del_write_in (wbs_sm_del_write_in), |
.del_error_in (wbs_sm_del_error_in), |
.wb_del_addr_in (wbs_sm_del_addr_in), |
.wb_del_be_in (wbs_sm_del_be_in), |
.wb_conf_offset_out (wbs_sm_conf_offset_out), |
.wb_conf_renable_out (wbs_sm_conf_renable_out), |
.wb_conf_wenable_out (wbs_sm_conf_wenable_out), |
.wb_conf_be_out (wbs_sm_conf_be_out), |
.wb_conf_data_in (wbs_sm_conf_data_in), |
.wb_conf_data_out (wbs_sm_conf_data_out), |
.wb_data_out (wbs_sm_data_out), |
.wb_cbe_out (wbs_sm_cbe_out), |
.wbw_fifo_wenable_out (wbs_sm_wbw_wenable_out), |
.wbw_fifo_control_out (wbs_sm_wbw_control_out), |
.wbw_fifo_almost_full_in (wbs_sm_wbw_almost_full_in), |
.wbw_fifo_full_in (wbs_sm_wbw_full_in), |
.wbr_fifo_renable_out (wbs_sm_wbr_renable_out), |
.wbr_fifo_be_in (wbs_sm_wbr_be_in), |
.wbr_fifo_data_in (wbs_sm_wbr_data_in), |
.wbr_fifo_control_in (wbs_sm_wbr_control_in), |
.wbr_fifo_flush_out (wbs_sm_wbr_flush_out), |
.wbr_fifo_empty_in (wbs_sm_wbr_empty_in), |
.pciw_fifo_empty_in (wbs_sm_pciw_empty_in), |
.wbs_lock_in (wbs_sm_lock_in), |
.cache_line_size_not_zero (wbs_sm_cache_line_size_not_zero), |
.del_in_progress_out (wbs_sm_del_in_progress_out), |
.ccyc_addr_in (wbs_sm_ccyc_addr_in), |
.sample_address_out (wbs_sm_sample_address_out), |
.CYC_I (wbs_sm_cyc_in), |
.STB_I (wbs_sm_stb_in), |
.WE_I (wbs_sm_we_in), |
.SEL_I (wbs_sm_sel_in), |
.SDATA_I (wbs_sm_sdata_in), |
.SDATA_O (wbs_sm_sdata_out), |
.ACK_O (wbs_sm_ack_out), |
.RTY_O (wbs_sm_rty_out), |
.ERR_O (wbs_sm_err_out), |
.CAB_I (wbs_sm_cab_in) |
); |
|
// wbw_wbr_fifos inputs |
// WBW_FIFO inputs |
wire fifos_wbw_wenable_in = wbs_sm_wbw_wenable_out; |
wire [31:0] fifos_wbw_addr_data_in = wbs_sm_data_out ; |
wire [3:0] fifos_wbw_cbe_in = wbs_sm_cbe_out ; |
wire [3:0] fifos_wbw_control_in = wbs_sm_wbw_control_out ; |
wire fifos_wbw_renable_in = pcim_if_wbw_renable_out ; |
|
//wire fifos_wbw_flush_in = 1'b0 ; flush for write fifo not used |
|
// WBR_FIFO inputs |
wire fifos_wbr_wenable_in = pcim_if_wbr_wenable_out ; |
wire [31:0] fifos_wbr_data_in = pcim_if_wbr_data_out ; |
wire [3:0] fifos_wbr_be_in = pcim_if_wbr_be_out ; |
wire [3:0] fifos_wbr_control_in = pcim_if_wbr_control_out ; |
wire fifos_wbr_renable_in = wbs_sm_wbr_renable_out ; |
wire fifos_wbr_flush_in = wbs_sm_wbr_flush_out || del_sync_comp_flush_out ; |
|
// WBW_FIFO and WBR_FIFO instantiation |
pci_wbw_wbr_fifos fifos |
( |
.wb_clock_in (wb_clock_in), |
.pci_clock_in (pci_clock_in), |
.reset_in (reset_in), |
.wbw_wenable_in (fifos_wbw_wenable_in), |
.wbw_addr_data_in (fifos_wbw_addr_data_in), |
.wbw_cbe_in (fifos_wbw_cbe_in), |
.wbw_control_in (fifos_wbw_control_in), |
.wbw_renable_in (fifos_wbw_renable_in), |
.wbw_addr_data_out (fifos_wbw_addr_data_out), |
.wbw_cbe_out (fifos_wbw_cbe_out), |
.wbw_control_out (fifos_wbw_control_out), |
// .wbw_flush_in (fifos_wbw_flush_in), // flush for write fifo not used |
.wbw_almost_full_out (fifos_wbw_almost_full_out), |
.wbw_full_out (fifos_wbw_full_out), |
.wbw_empty_out (fifos_wbw_empty_out), |
.wbw_transaction_ready_out (fifos_wbw_transaction_ready_out), |
.wbr_wenable_in (fifos_wbr_wenable_in), |
.wbr_data_in (fifos_wbr_data_in), |
.wbr_be_in (fifos_wbr_be_in), |
.wbr_control_in (fifos_wbr_control_in), |
.wbr_renable_in (fifos_wbr_renable_in), |
.wbr_data_out (fifos_wbr_data_out), |
.wbr_be_out (fifos_wbr_be_out), |
.wbr_control_out (fifos_wbr_control_out), |
.wbr_flush_in (fifos_wbr_flush_in), |
.wbr_empty_out (fifos_wbr_empty_out) |
|
`ifdef PCI_BIST |
, |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
) ; |
|
wire [31:0] amux_addr_in = ADDR_I ; |
wire amux_sample_address_in = wbs_sm_sample_address_out ; |
|
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar0_in = wbu_bar0_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar1_in = wbu_bar1_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar2_in = wbu_bar2_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar3_in = wbu_bar3_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar4_in = wbu_bar4_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar5_in = wbu_bar5_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am0_in = wbu_am0_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am1_in = wbu_am1_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am2_in = wbu_am2_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am3_in = wbu_am3_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am4_in = wbu_am4_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am5_in = wbu_am5_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta0_in = wbu_ta0_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta1_in = wbu_ta1_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta2_in = wbu_ta2_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta3_in = wbu_ta3_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta4_in = wbu_ta4_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta5_in = wbu_ta5_in ; |
wire [5:0] amux_at_en_in = wbu_at_en_in ; |
|
pci_wb_addr_mux wb_addr_dec |
( |
`ifdef REGISTER_WBS_OUTPUTS |
.clk_in (wb_clock_in), |
.reset_in (reset_in), |
.sample_address_in (amux_sample_address_in), |
`endif |
.address_in (amux_addr_in), |
.bar0_in (amux_bar0_in), |
.bar1_in (amux_bar1_in), |
.bar2_in (amux_bar2_in), |
.bar3_in (amux_bar3_in), |
.bar4_in (amux_bar4_in), |
.bar5_in (amux_bar5_in), |
.am0_in (amux_am0_in), |
.am1_in (amux_am1_in), |
.am2_in (amux_am2_in), |
.am3_in (amux_am3_in), |
.am4_in (amux_am4_in), |
.am5_in (amux_am5_in), |
.ta0_in (amux_ta0_in), |
.ta1_in (amux_ta1_in), |
.ta2_in (amux_ta2_in), |
.ta3_in (amux_ta3_in), |
.ta4_in (amux_ta4_in), |
.ta5_in (amux_ta5_in), |
.at_en_in (amux_at_en_in), |
.hit_out (amux_hit_out), |
.address_out (amux_address_out) |
); |
|
// delayed transaction logic inputs |
wire del_sync_req_in = wbs_sm_del_req_out ; |
wire del_sync_comp_in = pcim_if_del_complete_out ; |
wire del_sync_done_in = wbs_sm_del_done_out ; |
wire del_sync_in_progress_in = wbs_sm_del_in_progress_out ; |
wire [31:0] del_sync_addr_in = wbs_sm_data_out ; |
wire [3:0] del_sync_be_in = wbs_sm_conf_be_out ; |
wire del_sync_we_in = wbs_sm_del_write_out ; |
wire [3:0] del_sync_bc_in = wbs_sm_del_bc_out ; |
wire del_sync_status_in = pcim_if_del_error_out ; |
wire del_sync_burst_in = wbs_sm_del_burst_out ; |
wire del_sync_retry_expired_in = pcim_if_del_rty_exp_out ; |
|
// delayed transaction logic instantiation |
pci_delayed_sync del_sync ( |
.reset_in (reset_in), |
.req_clk_in (wb_clock_in), |
.comp_clk_in (pci_clock_in), |
.req_in (del_sync_req_in), |
.comp_in (del_sync_comp_in), |
.done_in (del_sync_done_in), |
.in_progress_in (del_sync_in_progress_in), |
.comp_req_pending_out (del_sync_comp_req_pending_out), |
.comp_comp_pending_out(del_sync_comp_comp_pending_out), |
.req_req_pending_out (del_sync_req_req_pending_out), |
.req_comp_pending_out (del_sync_req_comp_pending_out), |
.addr_in (del_sync_addr_in), |
.be_in (del_sync_be_in), |
.addr_out (del_sync_addr_out), |
.be_out (del_sync_be_out), |
.we_in (del_sync_we_in), |
.we_out (del_sync_we_out), |
.bc_in (del_sync_bc_in), |
.bc_out (del_sync_bc_out), |
.status_in (del_sync_status_in), |
.status_out (del_sync_status_out), |
.comp_flush_out (del_sync_comp_flush_out), |
.burst_in (del_sync_burst_in), |
.burst_out (del_sync_burst_out), |
.retry_expired_in (del_sync_retry_expired_in) |
); |
|
// delayed write storage inputs |
wire del_write_we_in = wbs_sm_del_req_out && wbs_sm_del_write_out ; |
wire [31:0] del_write_data_in = wbs_sm_conf_data_out ; |
|
pci_delayed_write_reg delayed_write_data |
( |
.reset_in (reset_in), |
.req_clk_in (wb_clock_in), |
.comp_wdata_out (del_write_data_out), |
.req_we_in (del_write_we_in), |
.req_wdata_in (del_write_data_in) |
); |
|
`ifdef HOST |
// configuration cycle address decoder input |
wire [31:0] ccyc_addr_in = {8'h00, wbu_ccyc_addr_in} ; |
|
pci_conf_cyc_addr_dec ccyc_addr_dec |
( |
.ccyc_addr_in (ccyc_addr_in), |
.ccyc_addr_out (ccyc_addr_out) |
) ; |
`else |
`ifdef GUEST |
assign ccyc_addr_out = 32'h0000_0000 ; |
`endif |
`endif |
|
// pci master interface inputs |
wire [31:0] pcim_if_wbw_addr_data_in = fifos_wbw_addr_data_out ; |
wire [3:0] pcim_if_wbw_cbe_in = fifos_wbw_cbe_out ; |
wire [3:0] pcim_if_wbw_control_in = fifos_wbw_control_out ; |
wire pcim_if_wbw_empty_in = fifos_wbw_empty_out ; |
wire pcim_if_wbw_transaction_ready_in = fifos_wbw_transaction_ready_out ; |
wire [31:0] pcim_if_data_in = pcim_sm_data_out ; |
wire [31:0] pcim_if_del_wdata_in = del_write_data_out ; |
wire pcim_if_del_req_in = del_sync_comp_req_pending_out ; |
wire [31:0] pcim_if_del_addr_in = del_sync_addr_out ; |
wire [3:0] pcim_if_del_bc_in = del_sync_bc_out ; |
wire [3:0] pcim_if_del_be_in = del_sync_be_out ; |
wire pcim_if_del_burst_in = del_sync_burst_out ; |
wire pcim_if_del_we_in = del_sync_we_out ; |
wire [7:0] pcim_if_cache_line_size_in = wbu_cache_line_size_in ; |
wire pcim_if_wait_in = pcim_sm_wait_out ; |
wire pcim_if_wtransfer_in = pcim_sm_wtransfer_out ; |
wire pcim_if_rtransfer_in = pcim_sm_rtransfer_out ; |
wire pcim_if_retry_in = pcim_sm_retry_out ; |
wire pcim_if_rerror_in = pcim_sm_rerror_out ; |
wire pcim_if_first_in = pcim_sm_first_out ; |
wire pcim_if_mabort_in = pcim_sm_mabort_out ; |
|
pci_master32_sm_if pci_initiator_if |
( |
.clk_in (pci_clock_in), |
.reset_in (reset_in), |
.address_out (pcim_if_address_out), |
.bc_out (pcim_if_bc_out), |
.data_out (pcim_if_data_out), |
.data_in (pcim_if_data_in), |
.be_out (pcim_if_be_out), |
.req_out (pcim_if_req_out), |
.rdy_out (pcim_if_rdy_out), |
.last_out (pcim_if_last_out), |
.wbw_renable_out (pcim_if_wbw_renable_out), |
.wbw_fifo_addr_data_in (pcim_if_wbw_addr_data_in), |
.wbw_fifo_cbe_in (pcim_if_wbw_cbe_in), |
.wbw_fifo_control_in (pcim_if_wbw_control_in), |
.wbw_fifo_empty_in (pcim_if_wbw_empty_in), |
.wbw_fifo_transaction_ready_in (pcim_if_wbw_transaction_ready_in), |
.wbr_fifo_wenable_out (pcim_if_wbr_wenable_out), |
.wbr_fifo_data_out (pcim_if_wbr_data_out), |
.wbr_fifo_be_out (pcim_if_wbr_be_out), |
.wbr_fifo_control_out (pcim_if_wbr_control_out), |
.del_wdata_in (pcim_if_del_wdata_in), |
.del_complete_out (pcim_if_del_complete_out), |
.del_req_in (pcim_if_del_req_in), |
.del_addr_in (pcim_if_del_addr_in), |
.del_bc_in (pcim_if_del_bc_in), |
.del_be_in (pcim_if_del_be_in), |
.del_burst_in (pcim_if_del_burst_in), |
.del_error_out (pcim_if_del_error_out), |
.del_rty_exp_out (pcim_if_del_rty_exp_out), |
.del_we_in (pcim_if_del_we_in), |
.err_addr_out (pcim_if_err_addr_out), |
.err_bc_out (pcim_if_err_bc_out), |
.err_signal_out (pcim_if_err_signal_out), |
.err_source_out (pcim_if_err_source_out), |
.err_rty_exp_out (pcim_if_err_rty_exp_out), |
.cache_line_size_in (pcim_if_cache_line_size_in), |
.mabort_received_out (pcim_if_mabort_out), |
.tabort_received_out (pcim_if_tabort_out), |
.next_data_out (pcim_if_next_data_out), |
.next_be_out (pcim_if_next_be_out), |
.next_last_out (pcim_if_next_last_out), |
.wait_in (pcim_if_wait_in), |
.wtransfer_in (pcim_if_wtransfer_in), |
.rtransfer_in (pcim_if_rtransfer_in), |
.retry_in (pcim_if_retry_in), |
.rerror_in (pcim_if_rerror_in), |
.first_in (pcim_if_first_in), |
.mabort_in (pcim_if_mabort_in), |
.posted_write_not_present_out (pcim_if_posted_write_not_present_out) |
); |
|
// pci master state machine inputs |
wire pcim_sm_gnt_in = wbu_pciif_gnt_in ; |
wire pcim_sm_frame_in = wbu_pciif_frame_in ; |
wire pcim_sm_irdy_in = wbu_pciif_irdy_in ; |
wire pcim_sm_trdy_in = wbu_pciif_trdy_in; |
wire pcim_sm_stop_in = wbu_pciif_stop_in ; |
wire pcim_sm_devsel_in = wbu_pciif_devsel_in ; |
wire [31:0] pcim_sm_ad_reg_in = wbu_pciif_ad_reg_in ; |
wire [31:0] pcim_sm_address_in = pcim_if_address_out ; |
wire [3:0] pcim_sm_bc_in = pcim_if_bc_out ; |
wire [31:0] pcim_sm_data_in = pcim_if_data_out ; |
wire [3:0] pcim_sm_be_in = pcim_if_be_out ; |
wire pcim_sm_req_in = pcim_if_req_out ; |
wire pcim_sm_rdy_in = pcim_if_rdy_out ; |
wire pcim_sm_last_in = pcim_if_last_out ; |
wire [7:0] pcim_sm_latency_tim_val_in = wbu_latency_tim_val_in ; |
wire [31:0] pcim_sm_next_data_in = pcim_if_next_data_out ; |
wire [3:0] pcim_sm_next_be_in = pcim_if_next_be_out ; |
wire pcim_sm_next_last_in = pcim_if_next_last_out ; |
wire pcim_sm_trdy_reg_in = wbu_pciif_trdy_reg_in ; |
wire pcim_sm_stop_reg_in = wbu_pciif_stop_reg_in ; |
wire pcim_sm_devsel_reg_in = wbu_pciif_devsel_reg_in ; |
wire pcim_sm_frame_en_in = wbu_pciif_frame_en_in ; |
wire pcim_sm_frame_out_in = wbu_pciif_frame_out_in ; |
|
pci_master32_sm pci_initiator_sm |
( |
.clk_in (pci_clock_in), |
.reset_in (reset_in), |
.pci_req_out (pcim_sm_req_out), |
.pci_gnt_in (pcim_sm_gnt_in), |
.pci_frame_in (pcim_sm_frame_in), |
.pci_frame_out (pcim_sm_frame_out), |
.pci_frame_en_out (pcim_sm_frame_en_out), |
.pci_frame_out_in (pcim_sm_frame_out_in), |
.pci_frame_load_out (pcim_sm_frame_load_out), |
.pci_frame_en_in (pcim_sm_frame_en_in), |
.pci_irdy_in (pcim_sm_irdy_in), |
.pci_irdy_out (pcim_sm_irdy_out), |
.pci_irdy_en_out (pcim_sm_irdy_en_out), |
.pci_trdy_in (pcim_sm_trdy_in), |
.pci_trdy_reg_in (pcim_sm_trdy_reg_in), |
.pci_stop_in (pcim_sm_stop_in), |
.pci_stop_reg_in (pcim_sm_stop_reg_in), |
.pci_devsel_in (pcim_sm_devsel_in), |
.pci_devsel_reg_in (pcim_sm_devsel_reg_in), |
.pci_ad_reg_in (pcim_sm_ad_reg_in), |
.pci_ad_out (pcim_sm_ad_out), |
.pci_ad_en_out (pcim_sm_ad_en_out), |
.pci_cbe_out (pcim_sm_cbe_out), |
.pci_cbe_en_out (pcim_sm_cbe_en_out), |
.address_in (pcim_sm_address_in), |
.bc_in (pcim_sm_bc_in), |
.data_in (pcim_sm_data_in), |
.data_out (pcim_sm_data_out), |
.be_in (pcim_sm_be_in), |
.req_in (pcim_sm_req_in), |
.rdy_in (pcim_sm_rdy_in), |
.last_in (pcim_sm_last_in), |
.latency_tim_val_in (pcim_sm_latency_tim_val_in), |
.next_data_in (pcim_sm_next_data_in), |
.next_be_in (pcim_sm_next_be_in), |
.next_last_in (pcim_sm_next_last_in), |
.ad_load_out (pcim_sm_ad_load_out), |
.ad_load_on_transfer_out (pcim_sm_ad_load_on_transfer_out), |
.wait_out (pcim_sm_wait_out), |
.wtransfer_out (pcim_sm_wtransfer_out), |
.rtransfer_out (pcim_sm_rtransfer_out), |
.retry_out (pcim_sm_retry_out), |
.rerror_out (pcim_sm_rerror_out), |
.first_out (pcim_sm_first_out), |
.mabort_out (pcim_sm_mabort_out) |
) ; |
|
endmodule |
/verilog/top.v
0,0 → 1,496
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "top.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.11 2003/08/21 20:49:03 tadejm |
// Added signals for WB Master B3. |
// |
// Revision 1.10 2003/08/03 18:05:06 mihad |
// Added limited WISHBONE B3 support for WISHBONE Slave Unit. |
// Doesn't support full speed bursts yet. |
// |
// Revision 1.9 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.8 2002/10/18 03:36:37 tadejm |
// Changed wrong signal name mbist_sen into mbist_ctrl_i. |
// |
// Revision 1.7 2002/10/17 22:49:22 tadejm |
// Changed BIST signals for RAMs. |
// |
// Revision 1.6 2002/10/11 10:09:01 mihad |
// Added additional testcase and changed rst name in BIST to trst |
// |
// Revision 1.5 2002/10/08 17:17:06 mihad |
// Added BIST signals for RAMs. |
// |
// Revision 1.4 2002/03/21 07:36:04 mihad |
// Files updated with missing includes, resolved some race conditions in test bench |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// This top module is primarly used for testing plain PCI bridge core without any other cores attached. |
// Other cores can be included in this top module and appropriate changes incorporated for overall design |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "pci_constants.v" |
|
module TOP |
( |
CLK, |
AD, |
CBE, |
RST, |
INTA, |
REQ, |
GNT, |
FRAME, |
IRDY, |
IDSEL, |
DEVSEL, |
TRDY, |
STOP, |
PAR, |
PERR, |
SERR, |
|
CLK_I, |
RST_I, |
RST_O, |
INT_I, |
INT_O, |
|
// WISHBONE slave interface |
ADR_I, |
SDAT_I, |
SDAT_O, |
SEL_I, |
CYC_I, |
STB_I, |
WE_I, |
CAB_I, |
CTI_I, |
BTE_I, |
ACK_O, |
RTY_O, |
ERR_O, |
|
// WISHBONE master interface |
ADR_O, |
MDAT_I, |
MDAT_O, |
SEL_O, |
CYC_O, |
STB_O, |
WE_O, |
CTI_O, |
BTE_O, |
ACK_I, |
RTY_I, |
ERR_I |
|
`ifdef PCI_BIST |
, |
// debug chain signals |
mbist_si_i, // bist scan serial in |
mbist_so_o, // bist scan serial out |
mbist_ctrl_i // bist chain shift control |
`endif |
); |
|
input CLK ; |
inout [31:0] AD ; |
inout [3:0] CBE ; |
inout RST ; |
inout INTA ; |
output REQ ; |
input GNT ; |
inout FRAME ; |
inout IRDY ; |
input IDSEL ; |
inout DEVSEL ; |
inout TRDY ; |
inout STOP ; |
inout PAR ; |
inout PERR ; |
output SERR ; |
|
// WISHBONE system signals |
input CLK_I ; |
input RST_I ; |
output RST_O ; |
input INT_I ; |
output INT_O ; |
|
// WISHBONE slave interface |
input [31:0] ADR_I ; |
input [31:0] SDAT_I ; |
output [31:0] SDAT_O ; |
input [3:0] SEL_I ; |
input CYC_I ; |
input STB_I ; |
input WE_I ; |
input CAB_I ; |
input [ 2:0] CTI_I ; |
input [ 1:0] BTE_I ; |
output ACK_O ; |
output RTY_O ; |
output ERR_O ; |
|
// WISHBONE master interface |
output [31:0] ADR_O ; |
input [31:0] MDAT_I ; |
output [31:0] MDAT_O ; |
output [3:0] SEL_O ; |
output CYC_O ; |
output STB_O ; |
output WE_O ; |
output [2:0] CTI_O ; |
output [1:0] BTE_O ; |
input ACK_I ; |
input RTY_I ; |
input ERR_I ; |
|
`ifdef PCI_BIST |
/*----------------------------------------------------- |
BIST debug chain port signals |
-----------------------------------------------------*/ |
input mbist_si_i; // bist scan serial in |
output mbist_so_o; // bist scan serial out |
input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control |
`endif |
|
wire [31:0] AD_out ; |
wire [31:0] AD_en ; |
|
|
wire [31:0] AD_in = AD ; |
|
wire [3:0] CBE_in = CBE ; |
wire [3:0] CBE_out ; |
wire [3:0] CBE_en ; |
|
|
|
wire RST_in = RST ; |
wire RST_out ; |
wire RST_en ; |
|
wire INTA_in = INTA ; |
wire INTA_en ; |
wire INTA_out ; |
|
wire REQ_en ; |
wire REQ_out ; |
|
wire FRAME_in = FRAME ; |
wire FRAME_out ; |
wire FRAME_en ; |
|
wire IRDY_in = IRDY ; |
wire IRDY_out ; |
wire IRDY_en ; |
|
wire DEVSEL_in = DEVSEL ; |
wire DEVSEL_out ; |
wire DEVSEL_en ; |
|
wire TRDY_in = TRDY ; |
wire TRDY_out ; |
wire TRDY_en ; |
|
wire STOP_in = STOP ; |
wire STOP_out ; |
wire STOP_en ; |
|
wire PAR_in = PAR ; |
wire PAR_out ; |
wire PAR_en ; |
|
wire PERR_in = PERR ; |
wire PERR_out ; |
wire PERR_en ; |
|
wire SERR_out ; |
wire SERR_en ; |
|
pci_bridge32 bridge |
( |
// WISHBONE system signals |
.wb_clk_i(CLK_I), |
.wb_rst_i(RST_I), |
.wb_rst_o(RST_O), |
.wb_int_i(INT_I), |
.wb_int_o(INT_O), |
|
// WISHBONE slave interface |
.wbs_adr_i(ADR_I), |
.wbs_dat_i(SDAT_I), |
.wbs_dat_o(SDAT_O), |
.wbs_sel_i(SEL_I), |
.wbs_cyc_i(CYC_I), |
.wbs_stb_i(STB_I), |
.wbs_we_i (WE_I), |
|
`ifdef PCI_WB_REV_B3 |
|
.wbs_cti_i(CTI_I), |
.wbs_bte_i(BTE_I), |
|
`else |
|
.wbs_cab_i(CAB_I), |
|
`endif |
|
.wbs_ack_o(ACK_O), |
.wbs_rty_o(RTY_O), |
.wbs_err_o(ERR_O), |
|
// WISHBONE master interface |
.wbm_adr_o(ADR_O), |
.wbm_dat_i(MDAT_I), |
.wbm_dat_o(MDAT_O), |
.wbm_sel_o(SEL_O), |
.wbm_cyc_o(CYC_O), |
.wbm_stb_o(STB_O), |
.wbm_we_o (WE_O), |
.wbm_cti_o(CTI_O), |
.wbm_bte_o(BTE_O), |
.wbm_ack_i(ACK_I), |
.wbm_rty_i(RTY_I), |
.wbm_err_i(ERR_I), |
|
// pci interface - system pins |
.pci_clk_i (CLK), |
.pci_rst_i ( RST_in ), |
.pci_rst_o ( RST_out ), |
.pci_inta_i ( INTA_in ), |
.pci_inta_o ( INTA_out), |
.pci_rst_oe_o ( RST_en), |
.pci_inta_oe_o(INTA_en), |
|
// arbitration pins |
.pci_req_o ( REQ_out ), |
.pci_req_oe_o( REQ_en ), |
|
.pci_gnt_i ( GNT ), |
|
// protocol pins |
.pci_frame_i ( FRAME_in), |
.pci_frame_o ( FRAME_out ), |
|
.pci_frame_oe_o( FRAME_en ), |
.pci_irdy_oe_o ( IRDY_en ), |
.pci_devsel_oe_o( DEVSEL_en ), |
.pci_trdy_oe_o ( TRDY_en ), |
.pci_stop_oe_o ( STOP_en ), |
.pci_ad_oe_o (AD_en), |
.pci_cbe_oe_o ( CBE_en) , |
|
.pci_irdy_i ( IRDY_in ), |
.pci_irdy_o ( IRDY_out ), |
|
.pci_idsel_i ( IDSEL ), |
|
.pci_devsel_i ( DEVSEL_in ), |
.pci_devsel_o ( DEVSEL_out ), |
|
.pci_trdy_i ( TRDY_in ), |
.pci_trdy_o ( TRDY_out ), |
|
.pci_stop_i ( STOP_in ), |
.pci_stop_o ( STOP_out ), |
|
// data transfer pins |
.pci_ad_i(AD_in), |
.pci_ad_o(AD_out), |
|
.pci_cbe_i( CBE_in ), |
.pci_cbe_o( CBE_out ), |
|
// parity generation and checking pins |
.pci_par_i ( PAR_in ), |
.pci_par_o ( PAR_out ), |
.pci_par_oe_o ( PAR_en ), |
|
.pci_perr_i ( PERR_in ), |
.pci_perr_o ( PERR_out ), |
.pci_perr_oe_o( PERR_en ), |
|
// system error pin |
.pci_serr_o ( SERR_out ), |
.pci_serr_oe_o( SERR_en ) |
|
`ifdef PCI_BIST |
, |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
); |
|
|
// PCI IO buffers instantiation |
`ifdef ACTIVE_LOW_OE |
|
bufif0 AD_buf0 ( AD[0], AD_out[0], AD_en[0]) ; |
bufif0 AD_buf1 ( AD[1], AD_out[1], AD_en[1]) ; |
bufif0 AD_buf2 ( AD[2], AD_out[2], AD_en[2]) ; |
bufif0 AD_buf3 ( AD[3], AD_out[3], AD_en[3]) ; |
bufif0 AD_buf4 ( AD[4], AD_out[4], AD_en[4]) ; |
bufif0 AD_buf5 ( AD[5], AD_out[5], AD_en[5]) ; |
bufif0 AD_buf6 ( AD[6], AD_out[6], AD_en[6]) ; |
bufif0 AD_buf7 ( AD[7], AD_out[7], AD_en[7]) ; |
bufif0 AD_buf8 ( AD[8], AD_out[8], AD_en[8]) ; |
bufif0 AD_buf9 ( AD[9], AD_out[9], AD_en[9]) ; |
bufif0 AD_buf10 ( AD[10], AD_out[10],AD_en[10] ) ; |
bufif0 AD_buf11 ( AD[11], AD_out[11],AD_en[11] ) ; |
bufif0 AD_buf12 ( AD[12], AD_out[12],AD_en[12] ) ; |
bufif0 AD_buf13 ( AD[13], AD_out[13],AD_en[13] ) ; |
bufif0 AD_buf14 ( AD[14], AD_out[14],AD_en[14] ) ; |
bufif0 AD_buf15 ( AD[15], AD_out[15],AD_en[15] ) ; |
bufif0 AD_buf16 ( AD[16], AD_out[16],AD_en[16] ) ; |
bufif0 AD_buf17 ( AD[17], AD_out[17],AD_en[17] ) ; |
bufif0 AD_buf18 ( AD[18], AD_out[18],AD_en[18] ) ; |
bufif0 AD_buf19 ( AD[19], AD_out[19],AD_en[19] ) ; |
bufif0 AD_buf20 ( AD[20], AD_out[20],AD_en[20] ) ; |
bufif0 AD_buf21 ( AD[21], AD_out[21],AD_en[21] ) ; |
bufif0 AD_buf22 ( AD[22], AD_out[22],AD_en[22] ) ; |
bufif0 AD_buf23 ( AD[23], AD_out[23],AD_en[23] ) ; |
bufif0 AD_buf24 ( AD[24], AD_out[24],AD_en[24] ) ; |
bufif0 AD_buf25 ( AD[25], AD_out[25],AD_en[25] ) ; |
bufif0 AD_buf26 ( AD[26], AD_out[26],AD_en[26] ) ; |
bufif0 AD_buf27 ( AD[27], AD_out[27],AD_en[27] ) ; |
bufif0 AD_buf28 ( AD[28], AD_out[28],AD_en[28] ) ; |
bufif0 AD_buf29 ( AD[29], AD_out[29],AD_en[29] ) ; |
bufif0 AD_buf30 ( AD[30], AD_out[30],AD_en[30] ) ; |
bufif0 AD_buf31 ( AD[31], AD_out[31],AD_en[31] ) ; |
|
bufif0 CBE_buf0 ( CBE[0], CBE_out[0], CBE_en[0] ) ; |
bufif0 CBE_buf1 ( CBE[1], CBE_out[1], CBE_en[1] ) ; |
bufif0 CBE_buf2 ( CBE[2], CBE_out[2], CBE_en[2] ) ; |
bufif0 CBE_buf3 ( CBE[3], CBE_out[3], CBE_en[3] ) ; |
|
bufif0 FRAME_buf ( FRAME, FRAME_out, FRAME_en ) ; |
bufif0 IRDY_buf ( IRDY, IRDY_out, IRDY_en ) ; |
bufif0 DEVSEL_buf ( DEVSEL, DEVSEL_out, DEVSEL_en ) ; |
bufif0 TRDY_buf ( TRDY, TRDY_out, TRDY_en ) ; |
bufif0 STOP_buf ( STOP, STOP_out, STOP_en ) ; |
|
bufif0 RST_buf ( RST, RST_out, RST_en ) ; |
bufif0 INTA_buf ( INTA, INTA_out, INTA_en) ; |
bufif0 REQ_buf ( REQ, REQ_out, REQ_en ) ; |
bufif0 PAR_buf ( PAR, PAR_out, PAR_en ) ; |
bufif0 PERR_buf ( PERR, PERR_out, PERR_en ) ; |
bufif0 SERR_buf ( SERR, SERR_out, SERR_en ) ; |
|
`else |
`ifdef ACTIVE_HIGH_OE |
|
bufif1 AD_buf0 ( AD[0], AD_out[0], AD_en[0]) ; |
bufif1 AD_buf1 ( AD[1], AD_out[1], AD_en[1]) ; |
bufif1 AD_buf2 ( AD[2], AD_out[2], AD_en[2]) ; |
bufif1 AD_buf3 ( AD[3], AD_out[3], AD_en[3]) ; |
bufif1 AD_buf4 ( AD[4], AD_out[4], AD_en[4]) ; |
bufif1 AD_buf5 ( AD[5], AD_out[5], AD_en[5]) ; |
bufif1 AD_buf6 ( AD[6], AD_out[6], AD_en[6]) ; |
bufif1 AD_buf7 ( AD[7], AD_out[7], AD_en[7]) ; |
bufif1 AD_buf8 ( AD[8], AD_out[8], AD_en[8]) ; |
bufif1 AD_buf9 ( AD[9], AD_out[9], AD_en[9]) ; |
bufif1 AD_buf10 ( AD[10], AD_out[10],AD_en[10] ) ; |
bufif1 AD_buf11 ( AD[11], AD_out[11],AD_en[11] ) ; |
bufif1 AD_buf12 ( AD[12], AD_out[12],AD_en[12] ) ; |
bufif1 AD_buf13 ( AD[13], AD_out[13],AD_en[13] ) ; |
bufif1 AD_buf14 ( AD[14], AD_out[14],AD_en[14] ) ; |
bufif1 AD_buf15 ( AD[15], AD_out[15],AD_en[15] ) ; |
bufif1 AD_buf16 ( AD[16], AD_out[16],AD_en[16] ) ; |
bufif1 AD_buf17 ( AD[17], AD_out[17],AD_en[17] ) ; |
bufif1 AD_buf18 ( AD[18], AD_out[18],AD_en[18] ) ; |
bufif1 AD_buf19 ( AD[19], AD_out[19],AD_en[19] ) ; |
bufif1 AD_buf20 ( AD[20], AD_out[20],AD_en[20] ) ; |
bufif1 AD_buf21 ( AD[21], AD_out[21],AD_en[21] ) ; |
bufif1 AD_buf22 ( AD[22], AD_out[22],AD_en[22] ) ; |
bufif1 AD_buf23 ( AD[23], AD_out[23],AD_en[23] ) ; |
bufif1 AD_buf24 ( AD[24], AD_out[24],AD_en[24] ) ; |
bufif1 AD_buf25 ( AD[25], AD_out[25],AD_en[25] ) ; |
bufif1 AD_buf26 ( AD[26], AD_out[26],AD_en[26] ) ; |
bufif1 AD_buf27 ( AD[27], AD_out[27],AD_en[27] ) ; |
bufif1 AD_buf28 ( AD[28], AD_out[28],AD_en[28] ) ; |
bufif1 AD_buf29 ( AD[29], AD_out[29],AD_en[29] ) ; |
bufif1 AD_buf30 ( AD[30], AD_out[30],AD_en[30] ) ; |
bufif1 AD_buf31 ( AD[31], AD_out[31],AD_en[31] ) ; |
|
bufif1 CBE_buf0 ( CBE[0], CBE_out[0], CBE_en[0] ) ; |
bufif1 CBE_buf1 ( CBE[1], CBE_out[1], CBE_en[1] ) ; |
bufif1 CBE_buf2 ( CBE[2], CBE_out[2], CBE_en[2] ) ; |
bufif1 CBE_buf3 ( CBE[3], CBE_out[3], CBE_en[3] ) ; |
|
bufif1 FRAME_buf ( FRAME, FRAME_out, FRAME_en ) ; |
bufif1 IRDY_buf ( IRDY, IRDY_out, IRDY_en ) ; |
bufif1 DEVSEL_buf ( DEVSEL, DEVSEL_out, DEVSEL_en ) ; |
bufif1 TRDY_buf ( TRDY, TRDY_out, TRDY_en ) ; |
bufif1 STOP_buf ( STOP, STOP_out, STOP_en ) ; |
|
bufif1 RST_buf ( RST, RST_out, RST_en ) ; |
bufif1 INTA_buf ( INTA, INTA_out, INTA_en) ; |
bufif1 REQ_buf ( REQ, REQ_out, REQ_en ) ; |
bufif1 PAR_buf ( PAR, PAR_out, PAR_en ) ; |
bufif1 PERR_buf ( PERR, PERR_out, PERR_en ) ; |
bufif1 SERR_buf ( SERR, SERR_out, SERR_en ) ; |
`endif |
`endif |
|
|
endmodule |
/verilog/pci_wb_tpram.v
0,0 → 1,462
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Generic Two-Port Synchronous RAM //// |
//// //// |
//// This file is part of pci bridge project //// |
//// http://www.opencores.org/cvsweb.shtml/pci/ //// |
//// //// |
//// Description //// |
//// This block is a wrapper with common two-port //// |
//// synchronous memory interface for different //// |
//// types of ASIC and FPGA RAMs. Beside universal memory //// |
//// interface it also provides behavioral model of generic //// |
//// two-port synchronous RAM. //// |
//// It should be used in all OPENCORES designs that want to be //// |
//// portable accross different target technologies and //// |
//// independent of target memory. //// |
//// //// |
//// Supported ASIC RAMs are: //// |
//// - Artisan Double-Port Sync RAM //// |
//// - Avant! Two-Port Sync RAM (*) //// |
//// - Virage 2-port Sync RAM //// |
//// //// |
//// Supported FPGA RAMs are: //// |
//// - Xilinx Virtex RAMB4_S16_S16 //// |
//// //// |
//// To Do: //// |
//// - fix Avant! //// |
//// - xilinx rams need external tri-state logic //// |
//// - add additional RAMs (Altera, VS etc) //// |
//// //// |
//// Author(s): //// |
//// - Damjan Lampret, lampret@opencores.org //// |
//// - Miha Dolenc, mihad@opencores.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2003/08/14 13:06:03 simons |
// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.7 2002/10/18 03:36:37 tadejm |
// Changed wrong signal name mbist_sen into mbist_ctrl_i. |
// |
// Revision 1.6 2002/10/17 22:49:22 tadejm |
// Changed BIST signals for RAMs. |
// |
// Revision 1.5 2002/10/11 10:09:01 mihad |
// Added additional testcase and changed rst name in BIST to trst |
// |
// Revision 1.4 2002/10/08 17:17:06 mihad |
// Added BIST signals for RAMs. |
// |
// Revision 1.3 2002/09/30 17:22:27 mihad |
// Added support for Virtual Silicon two port RAM. Didn't run regression on it yet! |
// |
// Revision 1.2 2002/08/19 16:51:36 mihad |
// Extracted distributed RAM module from wb/pci_tpram.v to its own file, got rid of undef directives |
// |
// Revision 1.1 2002/02/01 14:43:31 mihad |
// *** empty log message *** |
// |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "pci_constants.v" |
|
module pci_wb_tpram |
( |
// Generic synchronous two-port RAM interface |
clk_a, |
rst_a, |
ce_a, |
we_a, |
oe_a, |
addr_a, |
di_a, |
do_a, |
clk_b, |
rst_b, |
ce_b, |
we_b, |
oe_b, |
addr_b, |
di_b, |
do_b |
`ifdef PCI_BIST |
, |
// debug chain signals |
mbist_si_i, // bist scan serial in |
mbist_so_o, // bist scan serial out |
mbist_ctrl_i // bist chain shift control |
`endif |
); |
|
// |
// Default address and data buses width |
// |
parameter aw = 8; |
parameter dw = 40; |
|
// |
// Generic synchronous two-port RAM interface |
// |
input clk_a; // Clock |
input rst_a; // Reset |
input ce_a; // Chip enable input |
input we_a; // Write enable input |
input oe_a; // Output enable input |
input [aw-1:0] addr_a; // address bus inputs |
input [dw-1:0] di_a; // input data bus |
output [dw-1:0] do_a; // output data bus |
input clk_b; // Clock |
input rst_b; // Reset |
input ce_b; // Chip enable input |
input we_b; // Write enable input |
input oe_b; // Output enable input |
input [aw-1:0] addr_b; // address bus inputs |
input [dw-1:0] di_b; // input data bus |
output [dw-1:0] do_b; // output data bus |
|
`ifdef PCI_BIST |
// debug chain signals |
input mbist_si_i; // bist scan serial in |
output mbist_so_o; // bist scan serial out |
input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control |
`endif |
|
// |
// Internal wires and registers |
// |
|
`ifdef WB_VS_STP |
`define PCI_WB_RAM_SELECTED |
`ifdef PCI_BIST |
vs_hdtp_64x40_bist i_vs_hdtp_64x40_bist |
`else |
vs_hdtp_64x40 i_vs_hdtp_64x40 |
`endif |
( |
.RCK (clk_b), |
.WCK (clk_a), |
.RADR (addr_b), |
.WADR (addr_a), |
.DI (di_a), |
.DOUT (do_b), |
.REN (1'b0), |
.WEN (!we_a) |
`ifdef PCI_BIST |
, |
// debug chain signals |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
); |
|
assign do_a = 0 ; |
`endif |
|
`ifdef WB_ARTISAN_SDP |
`define PCI_WB_RAM_SELECTED |
// |
// Instantiation of ASIC memory: |
// |
// Artisan Synchronous Double-Port RAM (ra2sh) |
// |
`ifdef PCI_BIST |
art_hsdp_64x40_bist /*#(dw, 1<<aw, aw) */ artisan_sdp |
( |
.QA(do_a), |
.CLKA(clk_a), |
.CENA(~ce_a), |
.WENA(~we_a), |
.AA(addr_a), |
.DA(di_a), |
.OENA(~oe_a), |
.QB(do_b), |
.CLKB(clk_b), |
.CENB(~ce_b), |
.WENB(~we_b), |
.AB(addr_b), |
.DB(di_b), |
.OENB(~oe_b), |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
); |
`else |
art_hsdp_64x40 /*#(dw, 1<<aw, aw) */ artisan_sdp |
( |
.QA(do_a), |
.CLKA(clk_a), |
.CENA(~ce_a), |
.WENA(~we_a), |
.AA(addr_a), |
.DA(di_a), |
.OENA(~oe_a), |
.QB(do_b), |
.CLKB(clk_b), |
.CENB(~ce_b), |
.WENB(~we_b), |
.AB(addr_b), |
.DB(di_b), |
.OENB(~oe_b) |
); |
`endif |
`endif |
|
`ifdef AVANT_ATP |
`define PCI_WB_RAM_SELECTED |
// |
// Instantiation of ASIC memory: |
// |
// Avant! Asynchronous Two-Port RAM |
// |
avant_atp avant_atp( |
.web(~we), |
.reb(), |
.oeb(~oe), |
.rcsb(), |
.wcsb(), |
.ra(addr), |
.wa(addr), |
.di(di), |
.do(do) |
); |
|
`endif |
|
`ifdef VIRAGE_STP |
`define PCI_WB_RAM_SELECTED |
// |
// Instantiation of ASIC memory: |
// |
// Virage Synchronous 2-port R/W RAM |
// |
virage_stp virage_stp( |
.QA(do_a), |
.QB(do_b), |
|
.ADRA(addr_a), |
.DA(di_a), |
.WEA(we_a), |
.OEA(oe_a), |
.MEA(ce_a), |
.CLKA(clk_a), |
|
.ADRB(adr_b), |
.DB(di_b), |
.WEB(we_b), |
.OEB(oe_b), |
.MEB(ce_b), |
.CLKB(clk_b) |
); |
|
`endif |
|
`ifdef WB_XILINX_DIST_RAM |
`define PCI_WB_RAM_SELECTED |
|
reg [(aw-1):0] out_address ; |
always@(posedge clk_b or posedge rst_b) |
begin |
if ( rst_b ) |
out_address <= #1 0 ; |
else if (ce_b) |
out_address <= #1 addr_b ; |
end |
|
pci_ram_16x40d #(aw) wb_distributed_ram |
( |
.data_out (do_b), |
.we (we_a), |
.data_in (di_a), |
.read_address (out_address), |
.write_address (addr_a), |
.wclk (clk_a) |
); |
assign do_a = 0 ; |
`endif |
`ifdef WB_XILINX_RAMB4 |
`define PCI_WB_RAM_SELECTED |
// |
// Instantiation of FPGA memory: |
// |
// Virtex/Spartan2 |
// |
|
// |
// Block 0 |
// |
|
RAMB4_S16_S16 ramb4_s16_s16_0( |
.CLKA(clk_a), |
.RSTA(rst_a), |
.ADDRA(addr_a), |
.DIA(di_a[15:0]), |
.ENA(ce_a), |
.WEA(we_a), |
.DOA(do_a[15:0]), |
|
.CLKB(clk_b), |
.RSTB(rst_b), |
.ADDRB(addr_b), |
.DIB(di_b[15:0]), |
.ENB(ce_b), |
.WEB(we_b), |
.DOB(do_b[15:0]) |
); |
|
// |
// Block 1 |
// |
|
RAMB4_S16_S16 ramb4_s16_s16_1( |
.CLKA(clk_a), |
.RSTA(rst_a), |
.ADDRA(addr_a), |
.DIA(di_a[31:16]), |
.ENA(ce_a), |
.WEA(we_a), |
.DOA(do_a[31:16]), |
|
.CLKB(clk_b), |
.RSTB(rst_b), |
.ADDRB(addr_b), |
.DIB(di_b[31:16]), |
.ENB(ce_b), |
.WEB(we_b), |
.DOB(do_b[31:16]) |
); |
|
// |
// Block 2 |
// |
// block ram2 wires - non generic width of block rams |
wire [15:0] blk2_di_a = {8'h00, di_a[39:32]} ; |
wire [15:0] blk2_di_b = {8'h00, di_b[39:32]} ; |
|
wire [15:0] blk2_do_a ; |
wire [15:0] blk2_do_b ; |
|
assign do_a[39:32] = blk2_do_a[7:0] ; |
assign do_b[39:32] = blk2_do_b[7:0] ; |
|
RAMB4_S16_S16 ramb4_s16_s16_2( |
.CLKA(clk_a), |
.RSTA(rst_a), |
.ADDRA(addr_a), |
.DIA(blk2_di_a), |
.ENA(ce_a), |
.WEA(we_a), |
.DOA(blk2_do_a), |
|
.CLKB(clk_b), |
.RSTB(rst_b), |
.ADDRB(addr_b), |
.DIB(blk2_di_b), |
.ENB(ce_b), |
.WEB(we_b), |
.DOB(blk2_do_b) |
); |
|
`endif |
|
`ifdef PCI_WB_RAM_SELECTED |
`else |
// |
// Generic two-port synchronous RAM model |
// |
|
// |
// Generic RAM's registers and wires |
// |
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content |
reg [dw-1:0] do_reg_a; // RAM data output register |
reg [dw-1:0] do_reg_b; // RAM data output register |
|
// |
// Data output drivers |
// |
assign do_a = (oe_a) ? do_reg_a : {dw{1'bz}}; |
assign do_b = (oe_b) ? do_reg_b : {dw{1'bz}}; |
|
// |
// RAM read and write |
// |
always @(posedge clk_a) |
if (ce_a && !we_a) |
do_reg_a <= #1 mem[addr_a]; |
else if (ce_a && we_a) |
mem[addr_a] <= #1 di_a; |
|
// |
// RAM read and write |
// |
always @(posedge clk_b) |
if (ce_b && !we_b) |
do_reg_b <= #1 mem[addr_b]; |
else if (ce_b && we_b) |
mem[addr_b] <= #1 di_b; |
`endif |
|
// synopsys translate_off |
initial |
begin |
if (dw !== 40) |
begin |
$display("RAM instantiation error! Expected RAM width %d, actual %h!", 40, dw) ; |
$finish ; |
end |
`ifdef XILINX_RAMB4 |
if (aw !== 8) |
begin |
$display("RAM instantiation error! Expected RAM address width %d, actual %h!", 40, aw) ; |
$finish ; |
end |
`endif |
// currenlty only artisan ram of depth 256 is supported - they don't provide generic ram models |
`ifdef ARTISAN_SDP |
if (aw !== 8) |
begin |
$display("RAM instantiation error! Expected RAM address width %d, actual %h!", 40, aw) ; |
$finish ; |
end |
`endif |
end |
// synopsys translate_on |
|
endmodule |
/verilog/pci_pci_tpram.v
0,0 → 1,461
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Generic Two-Port Synchronous RAM //// |
//// //// |
//// This file is part of pci bridge project //// |
//// http://www.opencores.org/cvsweb.shtml/pci/ //// |
//// //// |
//// Description //// |
//// This block is a wrapper with common two-port //// |
//// synchronous memory interface for different //// |
//// types of ASIC and FPGA RAMs. Beside universal memory //// |
//// interface it also provides behavioral model of generic //// |
//// two-port synchronous RAM. //// |
//// It should be used in all OPENCORES designs that want to be //// |
//// portable accross different target technologies and //// |
//// independent of target memory. //// |
//// //// |
//// Supported ASIC RAMs are: //// |
//// - Artisan Double-Port Sync RAM //// |
//// - Avant! Two-Port Sync RAM (*) //// |
//// - Virage 2-port Sync RAM //// |
//// //// |
//// Supported FPGA RAMs are: //// |
//// - Xilinx Virtex RAMB4_S16_S16 //// |
//// //// |
//// To Do: //// |
//// - fix Avant! //// |
//// - xilinx rams need external tri-state logic //// |
//// - add additional RAMs (Altera, VS etc) //// |
//// //// |
//// Author(s): //// |
//// - Damjan Lampret, lampret@opencores.org //// |
//// - Miha Dolenc, mihad@opencores.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2003/08/14 13:06:03 simons |
// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.7 2002/10/18 03:36:37 tadejm |
// Changed wrong signal name mbist_sen into mbist_ctrl_i. |
// |
// Revision 1.6 2002/10/17 22:51:08 tadejm |
// Changed BIST signals for RAMs. |
// |
// Revision 1.5 2002/10/11 10:09:01 mihad |
// Added additional testcase and changed rst name in BIST to trst |
// |
// Revision 1.4 2002/10/08 17:17:06 mihad |
// Added BIST signals for RAMs. |
// |
// Revision 1.3 2002/09/30 17:22:27 mihad |
// Added support for Virtual Silicon two port RAM. Didn't run regression on it yet! |
// |
// Revision 1.2 2002/08/19 16:51:36 mihad |
// Extracted distributed RAM module from wb/pci_tpram.v to its own file, got rid of undef directives |
// |
// Revision 1.1 2002/02/01 14:43:31 mihad |
// *** empty log message *** |
// |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "pci_constants.v" |
|
module pci_pci_tpram |
( |
// Generic synchronous two-port RAM interface |
clk_a, |
rst_a, |
ce_a, |
we_a, |
oe_a, |
addr_a, |
di_a, |
do_a, |
clk_b, |
rst_b, |
ce_b, |
we_b, |
oe_b, |
addr_b, |
di_b, |
do_b |
`ifdef PCI_BIST |
, |
// debug chain signals |
mbist_si_i, // bist scan serial in |
mbist_so_o, // bist scan serial out |
mbist_ctrl_i // bist chain shift control |
`endif |
); |
|
// |
// Default address and data buses width |
// |
parameter aw = 8; |
parameter dw = 40; |
|
// |
// Generic synchronous two-port RAM interface |
// |
input clk_a; // Clock |
input rst_a; // Reset |
input ce_a; // Chip enable input |
input we_a; // Write enable input |
input oe_a; // Output enable input |
input [aw-1:0] addr_a; // address bus inputs |
input [dw-1:0] di_a; // input data bus |
output [dw-1:0] do_a; // output data bus |
input clk_b; // Clock |
input rst_b; // Reset |
input ce_b; // Chip enable input |
input we_b; // Write enable input |
input oe_b; // Output enable input |
input [aw-1:0] addr_b; // address bus inputs |
input [dw-1:0] di_b; // input data bus |
output [dw-1:0] do_b; // output data bus |
|
`ifdef PCI_BIST |
// debug chain signals |
input mbist_si_i; // bist scan serial in |
output mbist_so_o; // bist scan serial out |
input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control |
`endif |
|
// |
// Internal wires and registers |
// |
|
`ifdef PCI_VS_STP |
`define PCI_PCI_RAM_SELECTED |
`ifdef PCI_BIST |
vs_hdtp_64x40_bist i_vs_hdtp_64x40_bist |
`else |
vs_hdtp_64x40 i_vs_hdtp_64x40 |
`endif |
( |
.RCK (clk_b), |
.WCK (clk_a), |
.RADR (addr_b), |
.WADR (addr_a), |
.DI (di_a), |
.DOUT (do_b), |
.REN (1'b0), |
.WEN (!we_a) |
`ifdef PCI_BIST |
, |
// debug chain signals |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
); |
|
assign do_a = 0 ; |
`endif |
|
`ifdef PCI_ARTISAN_SDP |
`define PCI_PCI_RAM_SELECTED |
// |
// Instantiation of ASIC memory: |
// |
// Artisan Synchronous Double-Port RAM (ra2sh) |
// |
`ifdef PCI_BIST |
art_hsdp_64x40_bist /*#(dw, 1<<aw, aw) */ artisan_sdp |
( |
.QA(do_a), |
.CLKA(clk_a), |
.CENA(~ce_a), |
.WENA(~we_a), |
.AA(addr_a), |
.DA(di_a), |
.OENA(~oe_a), |
.QB(do_b), |
.CLKB(clk_b), |
.CENB(~ce_b), |
.WENB(~we_b), |
.AB(addr_b), |
.DB(di_b), |
.OENB(~oe_b), |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
); |
`else |
art_hsdp_64x40 /*#(dw, 1<<aw, aw) */ artisan_sdp |
( |
.QA(do_a), |
.CLKA(clk_a), |
.CENA(~ce_a), |
.WENA(~we_a), |
.AA(addr_a), |
.DA(di_a), |
.OENA(~oe_a), |
.QB(do_b), |
.CLKB(clk_b), |
.CENB(~ce_b), |
.WENB(~we_b), |
.AB(addr_b), |
.DB(di_b), |
.OENB(~oe_b) |
); |
`endif |
`endif |
|
`ifdef AVANT_ATP |
`define PCI_PCI_RAM_SELECTED |
// |
// Instantiation of ASIC memory: |
// |
// Avant! Asynchronous Two-Port RAM |
// |
avant_atp avant_atp( |
.web(~we), |
.reb(), |
.oeb(~oe), |
.rcsb(), |
.wcsb(), |
.ra(addr), |
.wa(addr), |
.di(di), |
.do(do) |
); |
`endif |
|
`ifdef VIRAGE_STP |
`define PCI_PCI_RAM_SELECTED |
// |
// Instantiation of ASIC memory: |
// |
// Virage Synchronous 2-port R/W RAM |
// |
virage_stp virage_stp( |
.QA(do_a), |
.QB(do_b), |
|
.ADRA(addr_a), |
.DA(di_a), |
.WEA(we_a), |
.OEA(oe_a), |
.MEA(ce_a), |
.CLKA(clk_a), |
|
.ADRB(adr_b), |
.DB(di_b), |
.WEB(we_b), |
.OEB(oe_b), |
.MEB(ce_b), |
.CLKB(clk_b) |
); |
`endif |
|
`ifdef PCI_XILINX_RAMB4 |
`define PCI_PCI_RAM_SELECTED |
// |
// Instantiation of FPGA memory: |
// |
// Virtex/Spartan2 |
// |
|
// |
// Block 0 |
// |
|
RAMB4_S16_S16 ramb4_s16_s16_0( |
.CLKA(clk_a), |
.RSTA(rst_a), |
.ADDRA(addr_a), |
.DIA(di_a[15:0]), |
.ENA(ce_a), |
.WEA(we_a), |
.DOA(do_a[15:0]), |
|
.CLKB(clk_b), |
.RSTB(rst_b), |
.ADDRB(addr_b), |
.DIB(di_b[15:0]), |
.ENB(ce_b), |
.WEB(we_b), |
.DOB(do_b[15:0]) |
); |
|
// |
// Block 1 |
// |
|
RAMB4_S16_S16 ramb4_s16_s16_1( |
.CLKA(clk_a), |
.RSTA(rst_a), |
.ADDRA(addr_a), |
.DIA(di_a[31:16]), |
.ENA(ce_a), |
.WEA(we_a), |
.DOA(do_a[31:16]), |
|
.CLKB(clk_b), |
.RSTB(rst_b), |
.ADDRB(addr_b), |
.DIB(di_b[31:16]), |
.ENB(ce_b), |
.WEB(we_b), |
.DOB(do_b[31:16]) |
); |
|
// |
// Block 2 |
// |
// block ram2 wires - non generic width of block rams |
wire [15:0] blk2_di_a = {8'h00, di_a[39:32]} ; |
wire [15:0] blk2_di_b = {8'h00, di_b[39:32]} ; |
|
wire [15:0] blk2_do_a ; |
wire [15:0] blk2_do_b ; |
|
assign do_a[39:32] = blk2_do_a[7:0] ; |
assign do_b[39:32] = blk2_do_b[7:0] ; |
|
RAMB4_S16_S16 ramb4_s16_s16_2( |
.CLKA(clk_a), |
.RSTA(rst_a), |
.ADDRA(addr_a), |
.DIA(blk2_di_a), |
.ENA(ce_a), |
.WEA(we_a), |
.DOA(blk2_do_a), |
|
.CLKB(clk_b), |
.RSTB(rst_b), |
.ADDRB(addr_b), |
.DIB(blk2_di_b), |
.ENB(ce_b), |
.WEB(we_b), |
.DOB(blk2_do_b) |
); |
|
`endif |
|
`ifdef PCI_XILINX_DIST_RAM |
`define PCI_PCI_RAM_SELECTED |
reg [(aw-1):0] out_address ; |
always@(posedge clk_b or posedge rst_b) |
begin |
if ( rst_b ) |
out_address <= #1 0 ; |
else if (ce_b) |
out_address <= #1 addr_b ; |
end |
|
pci_ram_16x40d #(aw) pci_distributed_ram |
( |
.data_out (do_b), |
.we (we_a), |
.data_in (di_a), |
.read_address (out_address), |
.write_address (addr_a), |
.wclk (clk_a) |
); |
|
assign do_a = 0 ; |
`endif |
|
`ifdef PCI_PCI_RAM_SELECTED |
`else |
// |
// Generic two-port synchronous RAM model |
// |
|
// |
// Generic RAM's registers and wires |
// |
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content |
reg [dw-1:0] do_reg_a; // RAM data output register |
reg [dw-1:0] do_reg_b; // RAM data output register |
|
// |
// Data output drivers |
// |
assign do_a = (oe_a) ? do_reg_a : {dw{1'bz}}; |
assign do_b = (oe_b) ? do_reg_b : {dw{1'bz}}; |
|
// |
// RAM read and write |
// |
always @(posedge clk_a) |
if (ce_a && !we_a) |
do_reg_a <= #1 mem[addr_a]; |
else if (ce_a && we_a) |
mem[addr_a] <= #1 di_a; |
|
// |
// RAM read and write |
// |
always @(posedge clk_b) |
if (ce_b && !we_b) |
do_reg_b <= #1 mem[addr_b]; |
else if (ce_b && we_b) |
mem[addr_b] <= #1 di_b; |
`endif |
|
// synopsys translate_off |
initial |
begin |
if (dw !== 40) |
begin |
$display("RAM instantiation error! Expected RAM width %d, actual %h!", 40, dw) ; |
$finish ; |
end |
`ifdef XILINX_RAMB4 |
if (aw !== 8) |
begin |
$display("RAM instantiation error! Expected RAM address width %d, actual %h!", 40, aw) ; |
$finish ; |
end |
`endif |
// currenlty only artisan ram of depth 256 is supported - they don't provide generic ram models |
`ifdef ARTISAN_SDP |
if (aw !== 8) |
begin |
$display("RAM instantiation error! Expected RAM address width %d, actual %h!", 40, aw) ; |
$finish ; |
end |
`endif |
end |
// synopsys translate_on |
|
endmodule |
/verilog/pci_target_unit.v
0,0 → 1,928
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_target_unit.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.13 2003/08/21 20:55:14 tadejm |
// Corrected bug when writing to FIFO (now it is registered). |
// |
// Revision 1.12 2003/08/08 16:36:33 tadejm |
// Added 'three_left_out' to pci_pciw_fifo signaling three locations before full. Added comparison between current registered cbe and next unregistered cbe to signal wb_master whether it is allowed to performe burst or not. Due to this, I needed 'three_left_out' so that writing to pci_pciw_fifo can be registered, otherwise timing problems would occure. |
// |
// Revision 1.11 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.10 2002/10/18 03:36:37 tadejm |
// Changed wrong signal name mbist_sen into mbist_ctrl_i. |
// |
// Revision 1.9 2002/10/17 22:51:08 tadejm |
// Changed BIST signals for RAMs. |
// |
// Revision 1.8 2002/10/11 10:09:01 mihad |
// Added additional testcase and changed rst name in BIST to trst |
// |
// Revision 1.7 2002/10/08 17:17:05 mihad |
// Added BIST signals for RAMs. |
// |
// Revision 1.6 2002/09/25 15:53:52 mihad |
// Removed all logic from asynchronous reset network |
// |
// Revision 1.5 2002/03/05 11:53:47 mihad |
// Added some testcases, removed un-needed fifo signals |
// |
// Revision 1.4 2002/02/19 16:32:37 mihad |
// Modified testbench and fixed some bugs |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// Module instantiates and connects other modules lower in hierarcy |
// PCI target unit consists of modules that together form datapath |
// between external WISHBONE slaves and external PCI initiators |
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_target_unit |
( |
reset_in, |
wb_clock_in, |
pci_clock_in, |
|
pciu_wbm_adr_o, |
pciu_wbm_dat_o, |
pciu_wbm_dat_i, |
pciu_wbm_cyc_o, |
pciu_wbm_stb_o, |
pciu_wbm_we_o, |
pciu_wbm_cti_o, |
pciu_wbm_bte_o, |
pciu_wbm_sel_o, |
pciu_wbm_ack_i, |
pciu_wbm_rty_i, |
pciu_wbm_err_i, |
pciu_mem_enable_in, |
pciu_io_enable_in, |
pciu_map_in, |
pciu_pref_en_in, |
pciu_conf_data_in, |
pciu_wbw_fifo_empty_in, |
pciu_wbu_del_read_comp_pending_in, |
pciu_wbu_frame_en_in, |
pciu_bar0_in, |
pciu_bar1_in, |
pciu_bar2_in, |
pciu_bar3_in, |
pciu_bar4_in, |
pciu_bar5_in, |
pciu_am0_in, |
pciu_am1_in, |
pciu_am2_in, |
pciu_am3_in, |
pciu_am4_in, |
pciu_am5_in, |
pciu_ta0_in, |
pciu_ta1_in, |
pciu_ta2_in, |
pciu_ta3_in, |
pciu_ta4_in, |
pciu_ta5_in, |
pciu_at_en_in, |
pciu_cache_line_size_in, |
pciu_cache_lsize_not_zero_in, |
pciu_pciif_frame_in, |
pciu_pciif_irdy_in, |
pciu_pciif_idsel_in, |
pciu_pciif_frame_reg_in, |
pciu_pciif_irdy_reg_in, |
pciu_pciif_idsel_reg_in, |
pciu_pciif_ad_reg_in, |
pciu_pciif_cbe_reg_in, |
pciu_pciif_cbe_in, |
pciu_pciif_bckp_trdy_en_in, |
pciu_pciif_bckp_devsel_in, |
pciu_pciif_bckp_trdy_in, |
pciu_pciif_bckp_stop_in, |
pciu_pciif_trdy_reg_in, |
pciu_pciif_stop_reg_in, |
pciu_pciif_trdy_out, |
pciu_pciif_stop_out, |
pciu_pciif_devsel_out, |
pciu_pciif_trdy_en_out, |
pciu_pciif_stop_en_out, |
pciu_pciif_devsel_en_out, |
pciu_ad_load_out, |
pciu_ad_load_on_transfer_out, |
pciu_pciif_ad_out, |
pciu_pciif_ad_en_out, |
pciu_pciif_tabort_set_out, |
pciu_err_addr_out, |
pciu_err_bc_out, |
pciu_err_data_out, |
pciu_err_be_out, |
pciu_err_signal_out, |
pciu_err_source_out, |
pciu_err_rty_exp_out, |
pciu_conf_offset_out, |
pciu_conf_renable_out, |
pciu_conf_wenable_out, |
pciu_conf_be_out, |
pciu_conf_data_out, |
pciu_conf_select_out, |
pciu_pci_drcomp_pending_out, |
pciu_pciw_fifo_empty_out |
|
`ifdef PCI_BIST |
, |
// debug chain signals |
mbist_si_i, // bist scan serial in |
mbist_so_o, // bist scan serial out |
mbist_ctrl_i // bist chain shift control |
`endif |
); |
|
input reset_in, |
wb_clock_in, |
pci_clock_in ; |
|
output [31:0] pciu_wbm_adr_o ; |
output [31:0] pciu_wbm_dat_o ; |
input [31:0] pciu_wbm_dat_i ; |
output pciu_wbm_cyc_o ; |
output pciu_wbm_stb_o ; |
output pciu_wbm_we_o ; |
output [2:0] pciu_wbm_cti_o ; |
output [1:0] pciu_wbm_bte_o ; |
output [3:0] pciu_wbm_sel_o ; |
input pciu_wbm_ack_i ; |
input pciu_wbm_rty_i ; |
input pciu_wbm_err_i ; |
|
input pciu_wbw_fifo_empty_in ; |
input pciu_wbu_del_read_comp_pending_in ; |
input pciu_wbu_frame_en_in ; |
|
input pciu_mem_enable_in ; |
input pciu_io_enable_in ; |
input [5:0] pciu_map_in ; |
input [5:0] pciu_pref_en_in ; |
input [31:0] pciu_conf_data_in ; |
|
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar0_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar1_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar2_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar3_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar4_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar5_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am0_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am1_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am2_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am3_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am4_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am5_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta0_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta1_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta2_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta3_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta4_in ; |
input [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta5_in ; |
input [5:0] pciu_at_en_in ; |
|
input [7:0] pciu_cache_line_size_in ; |
input pciu_cache_lsize_not_zero_in ; |
|
input pciu_pciif_frame_in ; |
input pciu_pciif_irdy_in ; |
input pciu_pciif_idsel_in ; |
input pciu_pciif_frame_reg_in ; |
input pciu_pciif_irdy_reg_in ; |
input pciu_pciif_idsel_reg_in ; |
input [31:0] pciu_pciif_ad_reg_in ; |
input [3:0] pciu_pciif_cbe_reg_in ; |
input [3:0] pciu_pciif_cbe_in; |
input pciu_pciif_bckp_trdy_en_in ; |
input pciu_pciif_bckp_devsel_in ; |
input pciu_pciif_bckp_trdy_in ; |
input pciu_pciif_bckp_stop_in ; |
input pciu_pciif_trdy_reg_in ; |
input pciu_pciif_stop_reg_in ; |
|
|
output pciu_pciif_trdy_out ; |
output pciu_pciif_stop_out ; |
output pciu_pciif_devsel_out ; |
output pciu_pciif_trdy_en_out ; |
output pciu_pciif_stop_en_out ; |
output pciu_pciif_devsel_en_out ; |
output pciu_ad_load_out ; |
output pciu_ad_load_on_transfer_out ; |
output [31:0] pciu_pciif_ad_out ; |
output pciu_pciif_ad_en_out ; |
output pciu_pciif_tabort_set_out ; |
|
output [31:0] pciu_err_addr_out ; |
output [3:0] pciu_err_bc_out ; |
output [31:0] pciu_err_data_out ; |
output [3:0] pciu_err_be_out ; |
output pciu_err_signal_out ; |
output pciu_err_source_out ; |
output pciu_err_rty_exp_out ; |
|
output pciu_conf_select_out ; |
output [11:0] pciu_conf_offset_out ; |
output pciu_conf_renable_out ; |
output pciu_conf_wenable_out ; |
output [3:0] pciu_conf_be_out ; |
output [31:0] pciu_conf_data_out ; |
|
output pciu_pci_drcomp_pending_out ; |
output pciu_pciw_fifo_empty_out ; |
|
`ifdef PCI_BIST |
/*----------------------------------------------------- |
BIST debug chain port signals |
-----------------------------------------------------*/ |
input mbist_si_i; // bist scan serial in |
output mbist_so_o; // bist scan serial out |
input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control |
`endif |
|
|
// pci target state machine and interface outputs |
wire pcit_sm_trdy_out ; |
wire pcit_sm_stop_out ; |
wire pcit_sm_devsel_out ; |
wire pcit_sm_trdy_en_out ; |
wire pcit_sm_stop_en_out ; |
wire pcit_sm_devsel_en_out ; |
wire pcit_sm_ad_load_out ; |
wire pcit_sm_ad_load_on_transfer_out ; |
wire [31:0] pcit_sm_ad_out ; |
wire pcit_sm_ad_en_out ; |
wire [31:0] pcit_sm_address_out ; |
wire [3:0] pcit_sm_bc_out ; |
wire pcit_sm_bc0_out ; |
wire [31:0] pcit_sm_data_out ; |
wire [3:0] pcit_sm_be_out ; |
wire [3:0] pcit_sm_next_be_out ; |
wire pcit_sm_req_out ; |
wire pcit_sm_rdy_out ; |
wire pcit_sm_addr_phase_out ; |
wire pcit_sm_bckp_devsel_out ; |
wire pcit_sm_bckp_trdy_out ; |
wire pcit_sm_bckp_stop_out ; |
wire pcit_sm_last_reg_out ; |
wire pcit_sm_frame_reg_out ; |
wire pcit_sm_fetch_pcir_fifo_out ; |
wire pcit_sm_load_medium_reg_out ; |
wire pcit_sm_sel_fifo_mreg_out ; |
wire pcit_sm_sel_conf_fifo_out ; |
wire pcit_sm_fetch_conf_out ; |
wire pcit_sm_load_to_pciw_fifo_out ; |
wire pcit_sm_load_to_conf_out ; |
|
wire pcit_sm_target_abort_set_out ; // to conf space |
|
assign pciu_pciif_trdy_out = pcit_sm_trdy_out ; |
assign pciu_pciif_stop_out = pcit_sm_stop_out ; |
assign pciu_pciif_devsel_out = pcit_sm_devsel_out ; |
assign pciu_pciif_trdy_en_out = pcit_sm_trdy_en_out ; |
assign pciu_pciif_stop_en_out = pcit_sm_stop_en_out ; |
assign pciu_pciif_devsel_en_out = pcit_sm_devsel_en_out ; |
assign pciu_ad_load_out = pcit_sm_ad_load_out ; |
assign pciu_ad_load_on_transfer_out = pcit_sm_ad_load_on_transfer_out ; |
assign pciu_pciif_ad_out = pcit_sm_ad_out ; |
assign pciu_pciif_ad_en_out = pcit_sm_ad_en_out ; |
assign pciu_pciif_tabort_set_out = pcit_sm_target_abort_set_out ; |
|
wire pcit_if_addr_claim_out ; |
wire [31:0] pcit_if_data_out ; |
wire pcit_if_same_read_out ; |
wire pcit_if_norm_access_to_config_out ; |
wire pcit_if_read_completed_out ; |
wire pcit_if_read_processing_out ; |
wire pcit_if_target_abort_out ; |
wire pcit_if_disconect_wo_data_out ; |
wire pcit_if_disconect_w_data_out ; |
wire pcit_if_pciw_fifo_full_out ; |
wire pcit_if_pcir_fifo_data_err_out ; |
wire pcit_if_wbw_fifo_empty_out ; |
wire pcit_if_wbu_del_read_comp_pending_out ; |
wire pcit_if_req_out ; |
wire pcit_if_done_out ; |
wire pcit_if_in_progress_out ; |
wire [31:0] pcit_if_addr_out ; |
wire [3:0] pcit_if_be_out ; |
wire pcit_if_we_out ; |
wire [3:0] pcit_if_bc_out ; |
wire pcit_if_burst_ok_out ; |
wire pcit_if_pcir_fifo_renable_out ; |
wire pcit_if_pcir_fifo_flush_out ; |
wire pcit_if_pciw_fifo_wenable_out ; |
wire [31:0] pcit_if_pciw_fifo_addr_data_out ; |
wire [3:0] pcit_if_pciw_fifo_cbe_out ; |
wire [3:0] pcit_if_pciw_fifo_control_out ; |
wire pcit_if_conf_hit_out ; |
wire [11:0] pcit_if_conf_addr_out ; |
wire [31:0] pcit_if_conf_data_out ; |
wire [3:0] pcit_if_conf_be_out ; |
wire pcit_if_conf_we_out ; |
wire pcit_if_conf_re_out ; |
|
// pci target state machine outputs |
// pci interface signals |
assign pciu_conf_select_out = pcit_if_conf_hit_out ; |
assign pciu_conf_offset_out = pcit_if_conf_addr_out ; |
assign pciu_conf_renable_out = pcit_if_conf_re_out ; |
assign pciu_conf_wenable_out = pcit_if_conf_we_out ; |
assign pciu_conf_be_out = pcit_if_conf_be_out ; |
assign pciu_conf_data_out = pcit_if_conf_data_out ; |
|
// wishbone master state machine outputs |
wire wbm_sm_wb_read_done ; |
wire wbm_sm_write_attempt ; |
wire wbm_sm_pcir_fifo_wenable_out ; |
wire [31:0] wbm_sm_pcir_fifo_data_out ; |
wire [3:0] wbm_sm_pcir_fifo_be_out ; |
wire [3:0] wbm_sm_pcir_fifo_control_out ; |
wire wbm_sm_pciw_fifo_renable_out ; |
wire wbm_sm_pci_error_sig_out ; |
wire [3:0] wbm_sm_pci_error_bc ; |
wire wbm_sm_write_rty_cnt_exp_out ; |
wire wbm_sm_error_source_out ; |
wire wbm_sm_read_rty_cnt_exp_out ; |
wire wbm_sm_cyc_out ; |
wire wbm_sm_stb_out ; |
wire wbm_sm_we_out ; |
wire [2:0] wbm_sm_cti_out ; |
wire [1:0] wbm_sm_bte_out ; |
wire [3:0] wbm_sm_sel_out ; |
wire [31:0] wbm_sm_adr_out ; |
wire [31:0] wbm_sm_mdata_out ; |
|
assign pciu_err_addr_out = wbm_sm_adr_out ; |
assign pciu_err_bc_out = wbm_sm_pci_error_bc ; |
assign pciu_err_data_out = wbm_sm_mdata_out ; |
assign pciu_err_be_out = ~wbm_sm_sel_out ; |
assign pciu_err_signal_out = wbm_sm_pci_error_sig_out ; |
assign pciu_err_source_out = wbm_sm_error_source_out ; |
assign pciu_err_rty_exp_out = wbm_sm_write_rty_cnt_exp_out ; |
|
assign pciu_wbm_adr_o = wbm_sm_adr_out ; |
assign pciu_wbm_dat_o = wbm_sm_mdata_out ; |
assign pciu_wbm_cyc_o = wbm_sm_cyc_out ; |
assign pciu_wbm_stb_o = wbm_sm_stb_out ; |
assign pciu_wbm_we_o = wbm_sm_we_out ; |
assign pciu_wbm_cti_o = wbm_sm_cti_out ; |
assign pciu_wbm_bte_o = wbm_sm_bte_out ; |
assign pciu_wbm_sel_o = wbm_sm_sel_out ; |
|
// pciw_pcir fifo outputs |
|
// pciw_fifo_outputs: |
wire [31:0] fifos_pciw_addr_data_out ; |
wire [3:0] fifos_pciw_cbe_out ; |
wire [3:0] fifos_pciw_control_out ; |
wire fifos_pciw_three_left_out ; |
wire fifos_pciw_two_left_out ; |
wire fifos_pciw_almost_full_out ; |
wire fifos_pciw_full_out ; |
wire fifos_pciw_almost_empty_out ; |
wire fifos_pciw_empty_out ; |
wire fifos_pciw_transaction_ready_out ; |
|
assign pciu_pciw_fifo_empty_out = !wbm_sm_write_attempt; |
|
// pcir_fifo_outputs |
wire [31:0] fifos_pcir_data_out ; |
wire [3:0] fifos_pcir_be_out ; |
wire [3:0] fifos_pcir_control_out ; |
wire fifos_pcir_almost_empty_out ; |
wire fifos_pcir_empty_out ; |
|
// delayed transaction logic outputs |
wire [31:0] del_sync_addr_out ; |
wire [3:0] del_sync_be_out ; |
wire del_sync_we_out ; |
wire del_sync_comp_req_pending_out ; |
wire del_sync_comp_comp_pending_out ; |
wire del_sync_req_req_pending_out ; |
wire del_sync_req_comp_pending_out ; |
wire [3:0] del_sync_bc_out ; |
wire del_sync_status_out ; |
wire del_sync_comp_flush_out ; |
wire del_sync_burst_out ; |
|
assign pciu_pci_drcomp_pending_out = del_sync_comp_comp_pending_out ; |
|
// WISHBONE master interface inputs |
wire wbm_sm_pci_tar_read_request = del_sync_comp_req_pending_out ; |
wire [31:0] wbm_sm_pci_tar_address = del_sync_addr_out ; |
wire [3:0] wbm_sm_pci_tar_cmd = del_sync_bc_out ; |
wire [3:0] wbm_sm_pci_tar_be = del_sync_be_out ; |
wire wbm_sm_pci_tar_burst_ok = del_sync_burst_out ; |
wire [7:0] wbm_sm_pci_cache_line_size = pciu_cache_line_size_in ; |
wire wbm_sm_cache_lsize_not_zero_in = pciu_cache_lsize_not_zero_in ; |
wire [31:0] wbm_sm_pciw_fifo_addr_data_in = fifos_pciw_addr_data_out ; |
wire [3:0] wbm_sm_pciw_fifo_cbe_in = fifos_pciw_cbe_out ; |
wire [3:0] wbm_sm_pciw_fifo_control_in = fifos_pciw_control_out ; |
wire wbm_sm_pciw_fifo_almost_empty_in = fifos_pciw_almost_empty_out ; |
wire wbm_sm_pciw_fifo_empty_in = fifos_pciw_empty_out ; |
wire wbm_sm_pciw_fifo_transaction_ready_in = fifos_pciw_transaction_ready_out ; |
wire [31:0] wbm_sm_mdata_in = pciu_wbm_dat_i ; |
wire wbm_sm_ack_in = pciu_wbm_ack_i ; |
wire wbm_sm_rty_in = pciu_wbm_rty_i ; |
wire wbm_sm_err_in = pciu_wbm_err_i ; |
|
// WISHBONE master interface instantiation |
pci_wb_master wishbone_master |
( |
.wb_clock_in (wb_clock_in), |
.reset_in (reset_in), |
.pci_tar_read_request (wbm_sm_pci_tar_read_request), //in |
.pci_tar_address (wbm_sm_pci_tar_address), //in |
.pci_tar_cmd (wbm_sm_pci_tar_cmd), //in |
.pci_tar_be (wbm_sm_pci_tar_be), //in |
.pci_tar_burst_ok (wbm_sm_pci_tar_burst_ok), //in |
.pci_cache_line_size (wbm_sm_pci_cache_line_size), //in |
.cache_lsize_not_zero (wbm_sm_cache_lsize_not_zero_in), |
.wb_read_done_out (wbm_sm_wb_read_done), //out |
.w_attempt (wbm_sm_write_attempt), //out |
.pcir_fifo_wenable_out (wbm_sm_pcir_fifo_wenable_out), |
.pcir_fifo_data_out (wbm_sm_pcir_fifo_data_out), |
.pcir_fifo_be_out (wbm_sm_pcir_fifo_be_out), |
.pcir_fifo_control_out (wbm_sm_pcir_fifo_control_out), |
.pciw_fifo_renable_out (wbm_sm_pciw_fifo_renable_out), |
.pciw_fifo_addr_data_in (wbm_sm_pciw_fifo_addr_data_in), |
.pciw_fifo_cbe_in (wbm_sm_pciw_fifo_cbe_in), |
.pciw_fifo_control_in (wbm_sm_pciw_fifo_control_in), |
.pciw_fifo_almost_empty_in (wbm_sm_pciw_fifo_almost_empty_in), |
.pciw_fifo_empty_in (wbm_sm_pciw_fifo_empty_in), |
.pciw_fifo_transaction_ready_in (wbm_sm_pciw_fifo_transaction_ready_in), |
.pci_error_sig_out (wbm_sm_pci_error_sig_out), |
.pci_error_bc (wbm_sm_pci_error_bc), |
.write_rty_cnt_exp_out (wbm_sm_write_rty_cnt_exp_out), |
.error_source_out (wbm_sm_error_source_out), |
.read_rty_cnt_exp_out (wbm_sm_read_rty_cnt_exp_out), |
.wb_cyc_o (wbm_sm_cyc_out), |
.wb_stb_o (wbm_sm_stb_out), |
.wb_we_o (wbm_sm_we_out), |
.wb_cti_o (wbm_sm_cti_out), |
.wb_bte_o (wbm_sm_bte_out), |
.wb_sel_o (wbm_sm_sel_out), |
.wb_adr_o (wbm_sm_adr_out), |
.wb_dat_i (wbm_sm_mdata_in), |
.wb_dat_o (wbm_sm_mdata_out), |
.wb_ack_i (wbm_sm_ack_in), |
.wb_rty_i (wbm_sm_rty_in), |
.wb_err_i (wbm_sm_err_in) |
); |
|
// pciw_pcir_fifos inputs |
// PCIW_FIFO inputs |
wire fifos_pciw_wenable_in = pcit_if_pciw_fifo_wenable_out ; |
wire [31:0] fifos_pciw_addr_data_in = pcit_if_pciw_fifo_addr_data_out ; |
wire [3:0] fifos_pciw_cbe_in = pcit_if_pciw_fifo_cbe_out ; |
wire [3:0] fifos_pciw_control_in = pcit_if_pciw_fifo_control_out ; |
wire fifos_pciw_renable_in = wbm_sm_pciw_fifo_renable_out ; |
//wire fifos_pciw_flush_in = 1'b0 ; // flush not used for write fifo |
|
// PCIR_FIFO inputs |
wire fifos_pcir_wenable_in = wbm_sm_pcir_fifo_wenable_out ; |
wire [31:0] fifos_pcir_data_in = wbm_sm_pcir_fifo_data_out ; |
wire [3:0] fifos_pcir_be_in = wbm_sm_pcir_fifo_be_out ; |
wire [3:0] fifos_pcir_control_in = wbm_sm_pcir_fifo_control_out ; |
wire fifos_pcir_renable_in = pcit_if_pcir_fifo_renable_out ; |
wire fifos_pcir_flush_in = pcit_if_pcir_fifo_flush_out ; |
|
// PCIW_FIFO and PCIR_FIFO instantiation |
pci_pciw_pcir_fifos fifos |
( |
.wb_clock_in (wb_clock_in), |
.pci_clock_in (pci_clock_in), |
.reset_in (reset_in), |
.pciw_wenable_in (fifos_pciw_wenable_in), //for PCI Target !!! |
.pciw_addr_data_in (fifos_pciw_addr_data_in), //for PCI Target !!! |
.pciw_cbe_in (fifos_pciw_cbe_in), //for PCI Target !!! |
.pciw_control_in (fifos_pciw_control_in), //for PCI Target !!! |
.pciw_renable_in (fifos_pciw_renable_in), |
.pciw_addr_data_out (fifos_pciw_addr_data_out), |
.pciw_cbe_out (fifos_pciw_cbe_out), |
.pciw_control_out (fifos_pciw_control_out), |
// .pciw_flush_in (fifos_pciw_flush_in), // flush not used for write fifo |
.pciw_three_left_out (fifos_pciw_three_left_out), //for PCI Target !!! |
.pciw_two_left_out (fifos_pciw_two_left_out), //for PCI Target !!! |
.pciw_almost_full_out (fifos_pciw_almost_full_out), //for PCI Target !!! |
.pciw_full_out (fifos_pciw_full_out), //for PCI Target !!! |
.pciw_almost_empty_out (fifos_pciw_almost_empty_out), |
.pciw_empty_out (fifos_pciw_empty_out), |
.pciw_transaction_ready_out (fifos_pciw_transaction_ready_out), |
.pcir_wenable_in (fifos_pcir_wenable_in), |
.pcir_data_in (fifos_pcir_data_in), |
.pcir_be_in (fifos_pcir_be_in), |
.pcir_control_in (fifos_pcir_control_in), |
.pcir_renable_in (fifos_pcir_renable_in), //for PCI Target !!! |
.pcir_data_out (fifos_pcir_data_out), //for PCI Target !!! |
.pcir_be_out (fifos_pcir_be_out), //for PCI Target !!! |
.pcir_control_out (fifos_pcir_control_out), //for PCI Target !!! |
.pcir_flush_in (fifos_pcir_flush_in), //for PCI Target !!! |
.pcir_full_out (), |
.pcir_almost_empty_out (fifos_pcir_almost_empty_out), //for PCI Target !!! |
.pcir_empty_out (fifos_pcir_empty_out), //for PCI Target !!! |
.pcir_transaction_ready_out () |
|
`ifdef PCI_BIST |
, |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
) ; |
|
// delayed transaction logic inputs |
wire del_sync_req_in = pcit_if_req_out ; |
wire del_sync_comp_in = wbm_sm_wb_read_done ; |
wire del_sync_done_in = pcit_if_done_out ; |
wire del_sync_in_progress_in = pcit_if_in_progress_out ; |
wire [31:0] del_sync_addr_in = pcit_if_addr_out ; |
wire [3:0] del_sync_be_in = pcit_if_be_out ; |
wire del_sync_we_in = pcit_if_we_out ; |
wire [3:0] del_sync_bc_in = pcit_if_bc_out ; |
wire del_sync_status_in = 1'b0 ; |
wire del_sync_burst_in = pcit_if_burst_ok_out ; |
wire del_sync_retry_expired_in = wbm_sm_read_rty_cnt_exp_out ; |
|
// delayed transaction logic instantiation |
pci_delayed_sync del_sync |
( |
.reset_in (reset_in), |
.req_clk_in (pci_clock_in), |
.comp_clk_in (wb_clock_in), |
.req_in (del_sync_req_in), |
.comp_in (del_sync_comp_in), |
.done_in (del_sync_done_in), |
.in_progress_in (del_sync_in_progress_in), |
.comp_req_pending_out (del_sync_comp_req_pending_out), |
.comp_comp_pending_out (del_sync_comp_comp_pending_out), |
.req_req_pending_out (del_sync_req_req_pending_out), |
.req_comp_pending_out (del_sync_req_comp_pending_out), |
.addr_in (del_sync_addr_in), |
.be_in (del_sync_be_in), |
.addr_out (del_sync_addr_out), |
.be_out (del_sync_be_out), |
.we_in (del_sync_we_in), |
.we_out (del_sync_we_out), |
.bc_in (del_sync_bc_in), |
.bc_out (del_sync_bc_out), |
.status_in (del_sync_status_in), |
.status_out (del_sync_status_out), |
.comp_flush_out (del_sync_comp_flush_out), |
.burst_in (del_sync_burst_in), |
.burst_out (del_sync_burst_out), |
.retry_expired_in (del_sync_retry_expired_in) |
); |
|
// pci target interface inputs |
wire [31:0] pcit_if_address_in = pcit_sm_address_out ; |
wire [3:0] pcit_if_bc_in = pcit_sm_bc_out ; |
wire pcit_if_bc0_in = pcit_sm_bc0_out ; |
wire [31:0] pcit_if_data_in = pcit_sm_data_out ; |
wire [3:0] pcit_if_be_in = pcit_sm_be_out ; |
wire [3:0] pcit_if_next_be_in = pcit_sm_next_be_out ; |
wire pcit_if_req_in = pcit_sm_req_out ; |
wire pcit_if_rdy_in = pcit_sm_rdy_out ; |
wire pcit_if_addr_phase_in = pcit_sm_addr_phase_out ; |
wire pcit_if_bckp_devsel_in = pcit_sm_bckp_devsel_out ; |
wire pcit_if_bckp_trdy_in = pcit_sm_bckp_trdy_out ; |
wire pcit_if_bckp_stop_in = pcit_sm_bckp_stop_out ; |
wire pcit_if_last_reg_in = pcit_sm_last_reg_out ; |
wire pcit_if_frame_reg_in = pcit_sm_frame_reg_out ; |
wire pcit_if_fetch_pcir_fifo_in = pcit_sm_fetch_pcir_fifo_out ; |
wire pcit_if_load_medium_reg_in = pcit_sm_load_medium_reg_out ; |
wire pcit_if_sel_fifo_mreg_in = pcit_sm_sel_fifo_mreg_out ; |
wire pcit_if_sel_conf_fifo_in = pcit_sm_sel_conf_fifo_out ; |
wire pcit_if_fetch_conf_in = pcit_sm_fetch_conf_out ; |
wire pcit_if_load_to_pciw_fifo_in = pcit_sm_load_to_pciw_fifo_out ; |
wire pcit_if_load_to_conf_in = pcit_sm_load_to_conf_out ; |
wire pcit_if_req_req_pending_in = del_sync_req_req_pending_out ; |
wire pcit_if_req_comp_pending_in = del_sync_req_comp_pending_out ; |
wire pcit_if_status_in = del_sync_status_out ; |
wire [31:0] pcit_if_strd_addr_in = del_sync_addr_out ; |
wire [3:0] pcit_if_strd_bc_in = del_sync_bc_out ; |
wire pcit_if_comp_flush_in = del_sync_comp_flush_out ; |
wire [31:0] pcit_if_pcir_fifo_data_in = fifos_pcir_data_out ; |
wire [3:0] pcit_if_pcir_fifo_be_in = fifos_pcir_be_out ; |
wire [3:0] pcit_if_pcir_fifo_control_in = fifos_pcir_control_out ; |
wire pcit_if_pcir_fifo_almost_empty_in = fifos_pcir_almost_empty_out ; |
wire pcit_if_pcir_fifo_empty_in = fifos_pcir_empty_out ; |
wire pcit_if_pciw_fifo_three_left_in = fifos_pciw_three_left_out ; |
wire pcit_if_pciw_fifo_two_left_in = fifos_pciw_two_left_out ; |
wire pcit_if_pciw_fifo_almost_full_in = fifos_pciw_almost_full_out ; |
wire pcit_if_pciw_fifo_full_in = fifos_pciw_full_out ; |
wire pcit_if_wbw_fifo_empty_in = pciu_wbw_fifo_empty_in ; |
wire pcit_if_wbu_del_read_comp_pending_in = pciu_wbu_del_read_comp_pending_in ; |
wire [31:0] pcit_if_conf_data_in = pciu_conf_data_in ; |
wire pcit_if_mem_enable_in = pciu_mem_enable_in ; |
wire pcit_if_io_enable_in = pciu_io_enable_in ; |
wire pcit_if_mem_io_addr_space0_in = pciu_map_in[0] ; |
wire pcit_if_mem_io_addr_space1_in = pciu_map_in[1] ; |
wire pcit_if_mem_io_addr_space2_in = pciu_map_in[2] ; |
wire pcit_if_mem_io_addr_space3_in = pciu_map_in[3] ; |
wire pcit_if_mem_io_addr_space4_in = pciu_map_in[4] ; |
wire pcit_if_mem_io_addr_space5_in = pciu_map_in[5] ; |
wire pcit_if_pre_fetch_en0_in = pciu_pref_en_in[0] ; |
wire pcit_if_pre_fetch_en1_in = pciu_pref_en_in[1] ; |
wire pcit_if_pre_fetch_en2_in = pciu_pref_en_in[2] ; |
wire pcit_if_pre_fetch_en3_in = pciu_pref_en_in[3] ; |
wire pcit_if_pre_fetch_en4_in = pciu_pref_en_in[4] ; |
wire pcit_if_pre_fetch_en5_in = pciu_pref_en_in[5] ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr0_in = pciu_bar0_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr1_in = pciu_bar1_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr2_in = pciu_bar2_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr3_in = pciu_bar3_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr4_in = pciu_bar4_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr5_in = pciu_bar5_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask0_in = pciu_am0_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask1_in = pciu_am1_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask2_in = pciu_am2_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask3_in = pciu_am3_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask4_in = pciu_am4_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask5_in = pciu_am5_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_tran_addr0_in = pciu_ta0_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_tran_addr1_in = pciu_ta1_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_tran_addr2_in = pciu_ta2_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_tran_addr3_in = pciu_ta3_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_tran_addr4_in = pciu_ta4_in ; |
wire [(`PCI_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_tran_addr5_in = pciu_ta5_in ; |
wire pcit_if_addr_tran_en0_in = pciu_at_en_in[0] ; |
wire pcit_if_addr_tran_en1_in = pciu_at_en_in[1] ; |
wire pcit_if_addr_tran_en2_in = pciu_at_en_in[2] ; |
wire pcit_if_addr_tran_en3_in = pciu_at_en_in[3] ; |
wire pcit_if_addr_tran_en4_in = pciu_at_en_in[4] ; |
wire pcit_if_addr_tran_en5_in = pciu_at_en_in[5] ; |
|
pci_target32_interface pci_target_if |
( |
.clk_in (pci_clock_in), |
.reset_in (reset_in), |
.address_in (pcit_if_address_in), |
.addr_claim_out (pcit_if_addr_claim_out), |
.bc_in (pcit_if_bc_in), |
.bc0_in (pcit_if_bc0_in), |
.data_in (pcit_if_data_in), |
.data_out (pcit_if_data_out), |
.be_in (pcit_if_be_in), |
.next_be_in (pcit_if_next_be_in), |
.req_in (pcit_if_req_in), |
.rdy_in (pcit_if_rdy_in), |
.addr_phase_in (pcit_if_addr_phase_in), |
.bckp_devsel_in (pcit_if_bckp_devsel_in), |
.bckp_trdy_in (pcit_if_bckp_trdy_in), |
.bckp_stop_in (pcit_if_bckp_stop_in), |
.last_reg_in (pcit_if_last_reg_in), |
.frame_reg_in (pcit_if_frame_reg_in), |
.fetch_pcir_fifo_in (pcit_if_fetch_pcir_fifo_in), |
.load_medium_reg_in (pcit_if_load_medium_reg_in), |
.sel_fifo_mreg_in (pcit_if_sel_fifo_mreg_in), |
.sel_conf_fifo_in (pcit_if_sel_conf_fifo_in), |
.fetch_conf_in (pcit_if_fetch_conf_in), |
.load_to_pciw_fifo_in (pcit_if_load_to_pciw_fifo_in), |
.load_to_conf_in (pcit_if_load_to_conf_in), |
.same_read_out (pcit_if_same_read_out), |
.norm_access_to_config_out (pcit_if_norm_access_to_config_out), |
.read_completed_out (pcit_if_read_completed_out), |
.read_processing_out (pcit_if_read_processing_out), |
.target_abort_out (pcit_if_target_abort_out), |
.disconect_wo_data_out (pcit_if_disconect_wo_data_out), |
.disconect_w_data_out (pcit_if_disconect_w_data_out), |
.pciw_fifo_full_out (pcit_if_pciw_fifo_full_out), |
.pcir_fifo_data_err_out (pcit_if_pcir_fifo_data_err_out), |
.wbw_fifo_empty_out (pcit_if_wbw_fifo_empty_out), |
.wbu_del_read_comp_pending_out (pcit_if_wbu_del_read_comp_pending_out), |
.req_out (pcit_if_req_out), |
.done_out (pcit_if_done_out), |
.in_progress_out (pcit_if_in_progress_out), |
.req_req_pending_in (pcit_if_req_req_pending_in), |
.req_comp_pending_in (pcit_if_req_comp_pending_in), |
.addr_out (pcit_if_addr_out), |
.be_out (pcit_if_be_out), |
.we_out (pcit_if_we_out), |
.bc_out (pcit_if_bc_out), |
.burst_ok_out (pcit_if_burst_ok_out), |
.strd_addr_in (pcit_if_strd_addr_in), |
.strd_bc_in (pcit_if_strd_bc_in), |
.status_in (pcit_if_status_in), |
.comp_flush_in (pcit_if_comp_flush_in), |
.pcir_fifo_renable_out (pcit_if_pcir_fifo_renable_out), |
.pcir_fifo_data_in (pcit_if_pcir_fifo_data_in), |
.pcir_fifo_be_in (pcit_if_pcir_fifo_be_in), |
.pcir_fifo_control_in (pcit_if_pcir_fifo_control_in), |
.pcir_fifo_flush_out (pcit_if_pcir_fifo_flush_out), |
.pcir_fifo_almost_empty_in (pcit_if_pcir_fifo_almost_empty_in), |
.pcir_fifo_empty_in (pcit_if_pcir_fifo_empty_in), |
.pciw_fifo_wenable_out (pcit_if_pciw_fifo_wenable_out), |
.pciw_fifo_addr_data_out (pcit_if_pciw_fifo_addr_data_out), |
.pciw_fifo_cbe_out (pcit_if_pciw_fifo_cbe_out), |
.pciw_fifo_control_out (pcit_if_pciw_fifo_control_out), |
.pciw_fifo_three_left_in (pcit_if_pciw_fifo_three_left_in), |
.pciw_fifo_two_left_in (pcit_if_pciw_fifo_two_left_in), |
.pciw_fifo_almost_full_in (pcit_if_pciw_fifo_almost_full_in), |
.pciw_fifo_full_in (pcit_if_pciw_fifo_full_in), |
.wbw_fifo_empty_in (pcit_if_wbw_fifo_empty_in), |
.wbu_del_read_comp_pending_in (pcit_if_wbu_del_read_comp_pending_in), |
.conf_hit_out (pcit_if_conf_hit_out), |
.conf_addr_out (pcit_if_conf_addr_out), |
.conf_data_out (pcit_if_conf_data_out), |
.conf_data_in (pcit_if_conf_data_in), |
.conf_be_out (pcit_if_conf_be_out), |
.conf_we_out (pcit_if_conf_we_out), |
.conf_re_out (pcit_if_conf_re_out), |
.mem_enable_in (pcit_if_mem_enable_in), |
.io_enable_in (pcit_if_io_enable_in), |
.mem_io_addr_space0_in (pcit_if_mem_io_addr_space0_in), |
.mem_io_addr_space1_in (pcit_if_mem_io_addr_space1_in), |
.mem_io_addr_space2_in (pcit_if_mem_io_addr_space2_in), |
.mem_io_addr_space3_in (pcit_if_mem_io_addr_space3_in), |
.mem_io_addr_space4_in (pcit_if_mem_io_addr_space4_in), |
.mem_io_addr_space5_in (pcit_if_mem_io_addr_space5_in), |
.pre_fetch_en0_in (pcit_if_pre_fetch_en0_in), |
.pre_fetch_en1_in (pcit_if_pre_fetch_en1_in), |
.pre_fetch_en2_in (pcit_if_pre_fetch_en2_in), |
.pre_fetch_en3_in (pcit_if_pre_fetch_en3_in), |
.pre_fetch_en4_in (pcit_if_pre_fetch_en4_in), |
.pre_fetch_en5_in (pcit_if_pre_fetch_en5_in), |
.pci_base_addr0_in (pcit_if_pci_base_addr0_in), |
.pci_base_addr1_in (pcit_if_pci_base_addr1_in), |
.pci_base_addr2_in (pcit_if_pci_base_addr2_in), |
.pci_base_addr3_in (pcit_if_pci_base_addr3_in), |
.pci_base_addr4_in (pcit_if_pci_base_addr4_in), |
.pci_base_addr5_in (pcit_if_pci_base_addr5_in), |
.pci_addr_mask0_in (pcit_if_pci_addr_mask0_in), |
.pci_addr_mask1_in (pcit_if_pci_addr_mask1_in), |
.pci_addr_mask2_in (pcit_if_pci_addr_mask2_in), |
.pci_addr_mask3_in (pcit_if_pci_addr_mask3_in), |
.pci_addr_mask4_in (pcit_if_pci_addr_mask4_in), |
.pci_addr_mask5_in (pcit_if_pci_addr_mask5_in), |
.pci_tran_addr0_in (pcit_if_pci_tran_addr0_in), |
.pci_tran_addr1_in (pcit_if_pci_tran_addr1_in), |
.pci_tran_addr2_in (pcit_if_pci_tran_addr2_in), |
.pci_tran_addr3_in (pcit_if_pci_tran_addr3_in), |
.pci_tran_addr4_in (pcit_if_pci_tran_addr4_in), |
.pci_tran_addr5_in (pcit_if_pci_tran_addr5_in), |
.addr_tran_en0_in (pcit_if_addr_tran_en0_in), |
.addr_tran_en1_in (pcit_if_addr_tran_en1_in), |
.addr_tran_en2_in (pcit_if_addr_tran_en2_in), |
.addr_tran_en3_in (pcit_if_addr_tran_en3_in), |
.addr_tran_en4_in (pcit_if_addr_tran_en4_in), |
.addr_tran_en5_in (pcit_if_addr_tran_en5_in) |
) ; |
|
// pci target state machine inputs |
wire pcit_sm_frame_in = pciu_pciif_frame_in ; |
wire pcit_sm_irdy_in = pciu_pciif_irdy_in ; |
wire pcit_sm_idsel_in = pciu_pciif_idsel_in ; |
wire pcit_sm_frame_reg_in = pciu_pciif_frame_reg_in ; |
wire pcit_sm_irdy_reg_in = pciu_pciif_irdy_reg_in ; |
wire pcit_sm_idsel_reg_in = pciu_pciif_idsel_reg_in ; |
wire [31:0] pcit_sm_ad_reg_in = pciu_pciif_ad_reg_in ; |
wire [3:0] pcit_sm_cbe_reg_in = pciu_pciif_cbe_reg_in ; |
wire [3:0] pcit_sm_cbe_in = pciu_pciif_cbe_in ; |
wire pcit_sm_bckp_trdy_en_in = pciu_pciif_bckp_trdy_en_in ; |
wire pcit_sm_bckp_devsel_in = pciu_pciif_bckp_devsel_in ; |
wire pcit_sm_bckp_trdy_in = pciu_pciif_bckp_trdy_in ; |
wire pcit_sm_bckp_stop_in = pciu_pciif_bckp_stop_in ; |
wire pcit_sm_addr_claim_in = pcit_if_addr_claim_out ; |
wire [31:0] pcit_sm_data_in = pcit_if_data_out ; |
wire pcit_sm_same_read_in = pcit_if_same_read_out ; |
wire pcit_sm_norm_access_to_config_in = pcit_if_norm_access_to_config_out ; |
wire pcit_sm_read_completed_in = pcit_if_read_completed_out ; |
wire pcit_sm_read_processing_in = pcit_if_read_processing_out ; |
wire pcit_sm_target_abort_in = pcit_if_target_abort_out ; |
wire pcit_sm_disconect_wo_data_in = pcit_if_disconect_wo_data_out ; |
wire pcit_sm_disconect_w_data_in = pcit_if_disconect_w_data_out ; |
wire pcit_sm_pciw_fifo_full_in = pcit_if_pciw_fifo_full_out ; |
wire pcit_sm_pcir_fifo_data_err_in = pcit_if_pcir_fifo_data_err_out ; |
wire pcit_sm_wbw_fifo_empty_in = pcit_if_wbw_fifo_empty_out ; |
wire pcit_sm_wbu_del_read_comp_pending_in = pcit_if_wbu_del_read_comp_pending_out ; |
wire pcit_sm_wbu_frame_en_in = pciu_wbu_frame_en_in ; |
wire pcit_sm_trdy_reg_in = pciu_pciif_trdy_reg_in ; |
wire pcit_sm_stop_reg_in = pciu_pciif_stop_reg_in ; |
|
|
pci_target32_sm pci_target_sm |
( |
.clk_in (pci_clock_in), |
.reset_in (reset_in), |
.pci_frame_in (pcit_sm_frame_in), |
.pci_irdy_in (pcit_sm_irdy_in), |
.pci_idsel_in (pcit_sm_idsel_in), |
.pci_frame_reg_in (pcit_sm_frame_reg_in), |
.pci_irdy_reg_in (pcit_sm_irdy_reg_in), |
.pci_idsel_reg_in (pcit_sm_idsel_reg_in), |
.pci_trdy_out (pcit_sm_trdy_out), |
.pci_stop_out (pcit_sm_stop_out), |
.pci_devsel_out (pcit_sm_devsel_out), |
.pci_trdy_en_out (pcit_sm_trdy_en_out), |
.pci_stop_en_out (pcit_sm_stop_en_out), |
.pci_devsel_en_out (pcit_sm_devsel_en_out), |
.ad_load_out (pcit_sm_ad_load_out), |
.ad_load_on_transfer_out (pcit_sm_ad_load_on_transfer_out), |
.pci_ad_reg_in (pcit_sm_ad_reg_in), |
.pci_ad_out (pcit_sm_ad_out), |
.pci_ad_en_out (pcit_sm_ad_en_out), |
.pci_cbe_reg_in (pcit_sm_cbe_reg_in), |
.pci_cbe_in (pcit_sm_cbe_in), |
.bckp_trdy_en_in (pcit_sm_bckp_trdy_en_in), |
.bckp_devsel_in (pcit_sm_bckp_devsel_in), |
.bckp_trdy_in (pcit_sm_bckp_trdy_in), |
.bckp_stop_in (pcit_sm_bckp_stop_in), |
.pci_trdy_reg_in (pcit_sm_trdy_reg_in), |
.pci_stop_reg_in (pcit_sm_stop_reg_in), |
.address_out (pcit_sm_address_out), |
.addr_claim_in (pcit_sm_addr_claim_in), |
.bc_out (pcit_sm_bc_out), |
.bc0_out (pcit_sm_bc0_out), |
.data_out (pcit_sm_data_out), |
.data_in (pcit_sm_data_in), |
.be_out (pcit_sm_be_out), |
.next_be_out (pcit_sm_next_be_out), |
.req_out (pcit_sm_req_out), |
.rdy_out (pcit_sm_rdy_out), |
.addr_phase_out (pcit_sm_addr_phase_out), |
.bckp_devsel_out (pcit_sm_bckp_devsel_out), |
.bckp_trdy_out (pcit_sm_bckp_trdy_out), |
.bckp_stop_out (pcit_sm_bckp_stop_out), |
.last_reg_out (pcit_sm_last_reg_out), |
.frame_reg_out (pcit_sm_frame_reg_out), |
.fetch_pcir_fifo_out (pcit_sm_fetch_pcir_fifo_out), |
.load_medium_reg_out (pcit_sm_load_medium_reg_out), |
.sel_fifo_mreg_out (pcit_sm_sel_fifo_mreg_out), |
.sel_conf_fifo_out (pcit_sm_sel_conf_fifo_out), |
.fetch_conf_out (pcit_sm_fetch_conf_out), |
.load_to_pciw_fifo_out (pcit_sm_load_to_pciw_fifo_out), |
.load_to_conf_out (pcit_sm_load_to_conf_out), |
.same_read_in (pcit_sm_same_read_in), |
.norm_access_to_config_in (pcit_sm_norm_access_to_config_in), |
.read_completed_in (pcit_sm_read_completed_in), |
.read_processing_in (pcit_sm_read_processing_in), |
.target_abort_in (pcit_sm_target_abort_in), |
.disconect_wo_data_in (pcit_sm_disconect_wo_data_in), |
.disconect_w_data_in (pcit_sm_disconect_w_data_in), |
.target_abort_set_out (pcit_sm_target_abort_set_out), |
.pciw_fifo_full_in (pcit_sm_pciw_fifo_full_in), |
.pcir_fifo_data_err_in (pcit_sm_pcir_fifo_data_err_in), |
.wbw_fifo_empty_in (pcit_sm_wbw_fifo_empty_in), |
.wbu_del_read_comp_pending_in (pcit_sm_wbu_del_read_comp_pending_in), |
.wbu_frame_en_in (pcit_sm_wbu_frame_en_in) |
) ; |
|
endmodule |
/verilog/pci_wbw_wbr_fifos.v
0,0 → 1,590
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "wbw_wbr_fifos.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2003/08/14 13:06:03 simons |
// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. |
// |
// Revision 1.3 2003/03/26 13:16:18 mihad |
// Added the reset value parameter to the synchronizer flop module. |
// Added resets to all synchronizer flop instances. |
// Repaired initial sync value in fifos. |
// |
// Revision 1.2 2003/01/30 22:01:09 mihad |
// Updated synchronization in top level fifo modules. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.9 2002/10/18 03:36:37 tadejm |
// Changed wrong signal name mbist_sen into mbist_ctrl_i. |
// |
// Revision 1.8 2002/10/17 22:49:22 tadejm |
// Changed BIST signals for RAMs. |
// |
// Revision 1.7 2002/10/11 10:09:01 mihad |
// Added additional testcase and changed rst name in BIST to trst |
// |
// Revision 1.6 2002/10/08 17:17:06 mihad |
// Added BIST signals for RAMs. |
// |
// Revision 1.5 2002/09/30 16:03:04 mihad |
// Added meta flop module for easier meta stable FF identification during synthesis |
// |
// Revision 1.4 2002/09/25 15:53:52 mihad |
// Removed all logic from asynchronous reset network |
// |
// Revision 1.3 2002/02/01 15:25:14 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:20:12 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_wbw_wbr_fifos |
( |
wb_clock_in, |
pci_clock_in, |
reset_in, |
wbw_wenable_in, |
wbw_addr_data_in, |
wbw_cbe_in, |
wbw_control_in, |
wbw_renable_in, |
wbw_addr_data_out, |
wbw_cbe_out, |
wbw_control_out, |
// wbw_flush_in, write fifo flush not used |
wbw_almost_full_out, |
wbw_full_out, |
wbw_empty_out, |
wbw_transaction_ready_out, |
wbr_wenable_in, |
wbr_data_in, |
wbr_be_in, |
wbr_control_in, |
wbr_renable_in, |
wbr_data_out, |
wbr_be_out, |
wbr_control_out, |
wbr_flush_in, |
wbr_empty_out |
|
`ifdef PCI_BIST |
, |
// debug chain signals |
mbist_si_i, // bist scan serial in |
mbist_so_o, // bist scan serial out |
mbist_ctrl_i // bist chain shift control |
`endif |
) ; |
|
/*----------------------------------------------------------------------------------------------------------- |
System inputs: |
wb_clock_in - WISHBONE bus clock |
pci_clock_in - PCI bus clock |
reset_in - reset from control logic |
-------------------------------------------------------------------------------------------------------------*/ |
input wb_clock_in, pci_clock_in, reset_in ; |
|
/*----------------------------------------------------------------------------------------------------------- |
WISHBONE WRITE FIFO interface signals prefixed with wbw_ - FIFO is used for posted writes initiated by |
WISHBONE master, traveling through FIFO and are completed on PCI by PCI master interface |
|
write enable signal: |
wbw_wenable_in = write enable input for WBW_FIFO - driven by WISHBONE slave interface |
|
data input signals: |
wbw_addr_data_in = data input - data from WISHBONE bus - first entry of transaction is address others are data entries |
wbw_cbe_in = bus command/byte enable(~SEL[3:0]) input - first entry of transaction is bus command, other are byte enables |
wbw_control_in = control input - encoded control bus input |
|
read enable signal: |
wbw_renable_in = read enable input driven by PCI master interface |
|
data output signals: |
wbw_addr_data_out = data output - data from WISHBONE bus - first entry of transaction is address, others are data entries |
wbw_cbe_out = bus command/byte enable output - first entry of transaction is bus command, others are byte enables |
wbw_control_out = control input - encoded control bus input |
|
status signals - monitored by various resources in the core |
wbw_flush_in = flush signal input for WBW_FIFO - when asserted, fifo is flushed(emptied) |
wbw_almost_full_out = almost full output from WBW_FIFO |
wbw_full_out = full output from WBW_FIFO |
wbw_empty_out = empty output from WBW_FIFO |
wbw_transaction_ready_out = output indicating that one complete transaction is waiting in WBW_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
// input control and data |
input wbw_wenable_in ; |
input [31:0] wbw_addr_data_in ; |
input [3:0] wbw_cbe_in ; |
input [3:0] wbw_control_in ; |
|
// output control and data |
input wbw_renable_in ; |
output [31:0] wbw_addr_data_out ; |
output [3:0] wbw_cbe_out ; |
output [3:0] wbw_control_out ; |
|
// flush input |
// input wbw_flush_in ; // not used |
|
// status outputs |
output wbw_almost_full_out ; |
output wbw_full_out ; |
output wbw_empty_out ; |
output wbw_transaction_ready_out ; |
|
/*----------------------------------------------------------------------------------------------------------- |
WISHBONE READ FIFO interface signals prefixed with wbr_ - FIFO is used for holding delayed read completions |
initiated by master on WISHBONE bus and completed on PCI bus, |
|
write enable signal: |
wbr_wenable_in = write enable input for WBR_FIFO - driven by PCI master interface |
|
data input signals: |
wbr_data_in = data input - data from PCI bus - there is no address entry here, since address is stored in separate register |
wbr_be_in = byte enable(~BE#[3:0]) input - byte enables - same through one transaction |
wbr_control_in = control input - encoded control bus input |
|
read enable signal: |
wbr_renable_in = read enable input driven by WISHBONE slave interface |
|
data output signals: |
wbr_data_out = data output - data from PCI bus |
wbr_be_out = byte enable output(~#BE) |
wbr_control_out = control output - encoded control bus output |
|
status signals - monitored by various resources in the core |
wbr_flush_in = flush signal input for WBR_FIFO - when asserted, fifo is flushed(emptied) |
wbr full_out = full output from WBR_FIFO |
wbr_empty_out = empty output from WBR_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
// input control and data |
input wbr_wenable_in ; |
input [31:0] wbr_data_in ; |
input [3:0] wbr_be_in ; |
input [3:0] wbr_control_in ; |
|
// output control and data |
input wbr_renable_in ; |
output [31:0] wbr_data_out ; |
output [3:0] wbr_be_out ; |
output [3:0] wbr_control_out ; |
|
// flush input |
input wbr_flush_in ; |
|
output wbr_empty_out ; |
|
`ifdef PCI_BIST |
/*----------------------------------------------------- |
BIST debug chain port signals |
-----------------------------------------------------*/ |
input mbist_si_i; // bist scan serial in |
output mbist_so_o; // bist scan serial out |
input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control |
`endif |
|
/*----------------------------------------------------------------------------------------------------------- |
FIFO depth parameters: |
WBW_DEPTH = defines WBW_FIFO depth |
WBR_DEPTH = defines WBR_FIFO depth |
WBW_ADDR_LENGTH = defines WBW_FIFO's location address length = log2(WBW_DEPTH) |
WBR_ADDR_LENGTH = defines WBR_FIFO's location address length = log2(WBR_DEPTH) |
-----------------------------------------------------------------------------------------------------------*/ |
parameter WBW_DEPTH = `WBW_DEPTH ; |
parameter WBW_ADDR_LENGTH = `WBW_ADDR_LENGTH ; |
parameter WBR_DEPTH = `WBR_DEPTH ; |
parameter WBR_ADDR_LENGTH = `WBR_ADDR_LENGTH ; |
|
/*----------------------------------------------------------------------------------------------------------- |
wbw_wallow = WBW_FIFO write allow wire - writes to FIFO are allowed when FIFO isn't full and write enable is 1 |
wbw_rallow = WBW_FIFO read allow wire - reads from FIFO are allowed when FIFO isn't empty and read enable is 1 |
-----------------------------------------------------------------------------------------------------------*/ |
wire wbw_wallow ; |
wire wbw_rallow ; |
|
/*----------------------------------------------------------------------------------------------------------- |
wbr_wallow = WBR_FIFO write allow wire - writes to FIFO are allowed when FIFO isn't full and write enable is 1 |
wbr_rallow = WBR_FIFO read allow wire - reads from FIFO are allowed when FIFO isn't empty and read enable is 1 |
-----------------------------------------------------------------------------------------------------------*/ |
wire wbr_wallow ; |
wire wbr_rallow ; |
|
/*----------------------------------------------------------------------------------------------------------- |
wires for address port conections from WBW_FIFO control logic to RAM blocks used for WBW_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(WBW_ADDR_LENGTH - 1):0] wbw_raddr ; |
wire [(WBW_ADDR_LENGTH - 1):0] wbw_waddr ; |
|
/*----------------------------------------------------------------------------------------------------------- |
wires for address port conections from WBR_FIFO control logic to RAM blocks used for WBR_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(WBR_ADDR_LENGTH - 1):0] wbr_raddr ; |
wire [(WBR_ADDR_LENGTH - 1):0] wbr_waddr ; |
|
/*----------------------------------------------------------------------------------------------------------- |
WBW_FIFO transaction counters: used to count incoming transactions and outgoing transactions. When number of |
input transactions is equal to number of output transactions, it means that there isn't any complete transaction |
currently present in the FIFO. |
-----------------------------------------------------------------------------------------------------------*/ |
reg [(WBW_ADDR_LENGTH - 2):0] wbw_inTransactionCount ; |
reg [(WBW_ADDR_LENGTH - 2):0] wbw_outTransactionCount ; |
|
/*----------------------------------------------------------------------------------------------------------- |
wires monitoring control bus. When control bus on a write transaction has a value of `LAST, it means that |
complete transaction is in the FIFO. When control bus on a read transaction has a value of `LAST, |
it means that there was one complete transaction taken out of FIFO. |
-----------------------------------------------------------------------------------------------------------*/ |
wire wbw_last_in = wbw_control_in[`LAST_CTRL_BIT] ; |
wire wbw_last_out = wbw_control_out[`LAST_CTRL_BIT] ; |
|
wire wbw_empty ; |
wire wbr_empty ; |
|
assign wbw_empty_out = wbw_empty ; |
assign wbr_empty_out = wbr_empty ; |
|
// clear wires for fifos |
wire wbw_clear = reset_in /*|| wbw_flush_in*/ ; // WBW_FIFO clear flush not used |
wire wbr_clear = reset_in /*|| wbr_flush_in*/ ; // WBR_FIFO clear - flush changed from asynchronous to synchronous |
|
/*----------------------------------------------------------------------------------------------------------- |
Definitions of wires for connecting RAM instances |
-----------------------------------------------------------------------------------------------------------*/ |
wire [39:0] dpram_portA_output ; |
wire [39:0] dpram_portB_output ; |
|
wire [39:0] dpram_portA_input = {wbw_control_in, wbw_cbe_in, wbw_addr_data_in} ; |
wire [39:0] dpram_portB_input = {wbr_control_in, wbr_be_in, wbr_data_in} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Fifo output assignments - each ram port provides data for different fifo |
-----------------------------------------------------------------------------------------------------------*/ |
assign wbw_control_out = dpram_portB_output[39:36] ; |
assign wbr_control_out = dpram_portA_output[39:36] ; |
|
assign wbw_cbe_out = dpram_portB_output[35:32] ; |
assign wbr_be_out = dpram_portA_output[35:32] ; |
|
assign wbw_addr_data_out = dpram_portB_output[31:0] ; |
assign wbr_data_out = dpram_portA_output[31:0] ; |
|
`ifdef WB_RAM_DONT_SHARE |
|
/*----------------------------------------------------------------------------------------------------------- |
Piece of code in this ifdef section is used in applications which can provide enough RAM instances to |
accomodate four fifos - each occupying its own instance of ram. Ports are connected in such a way, |
that instances of RAMs can be changed from two port to dual port ( async read/write port ). In that case, |
write port is always port a and read port is port b. |
-----------------------------------------------------------------------------------------------------------*/ |
|
/*----------------------------------------------------------------------------------------------------------- |
Pad redundant address lines with zeros. This may seem stupid, but it comes in perfect for FPGA impl. |
-----------------------------------------------------------------------------------------------------------*/ |
/* |
wire [(`WBW_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH - 1):0] wbw_addr_prefix = {( `WBW_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH){1'b0}} ; |
wire [(`WBR_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH - 1):0] wbr_addr_prefix = {( `WBR_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH){1'b0}} ; |
*/ |
|
// compose complete port addresses |
wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbw_whole_waddr = wbw_waddr ; |
wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbw_whole_raddr = wbw_raddr ; |
|
wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbr_whole_waddr = wbr_waddr ; |
wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbr_whole_raddr = wbr_raddr ; |
|
wire wbw_read_enable = 1'b1 ; |
wire wbr_read_enable = 1'b1 ; |
|
`ifdef PCI_BIST |
wire mbist_so_o_internal ; // wires for connection of debug ports on two rams |
wire mbist_si_i_internal = mbist_so_o_internal ; |
`endif |
|
// instantiate and connect two generic rams - one for wishbone write fifo and one for wishbone read fifo |
pci_wb_tpram #(`WB_FIFO_RAM_ADDR_LENGTH, 40) wbw_fifo_storage |
( |
// Generic synchronous two-port RAM interface |
.clk_a(wb_clock_in), |
.rst_a(reset_in), |
.ce_a(1'b1), |
.we_a(wbw_wallow), |
.oe_a(1'b1), |
.addr_a(wbw_whole_waddr), |
.di_a(dpram_portA_input), |
.do_a(), |
|
.clk_b(pci_clock_in), |
.rst_b(reset_in), |
.ce_b(wbw_read_enable), |
.we_b(1'b0), |
.oe_b(1'b1), |
.addr_b(wbw_whole_raddr), |
.di_b(40'h00_0000_0000), |
.do_b(dpram_portB_output) |
|
`ifdef PCI_BIST |
, |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o_internal), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
); |
|
pci_wb_tpram #(`WB_FIFO_RAM_ADDR_LENGTH, 40) wbr_fifo_storage |
( |
// Generic synchronous two-port RAM interface |
.clk_a(pci_clock_in), |
.rst_a(reset_in), |
.ce_a(1'b1), |
.we_a(wbr_wallow), |
.oe_a(1'b1), |
.addr_a(wbr_whole_waddr), |
.di_a(dpram_portB_input), |
.do_a(), |
|
.clk_b(wb_clock_in), |
.rst_b(reset_in), |
.ce_b(wbr_read_enable), |
.we_b(1'b0), |
.oe_b(1'b1), |
.addr_b(wbr_whole_raddr), |
.di_b(40'h00_0000_0000), |
.do_b(dpram_portA_output) |
|
`ifdef PCI_BIST |
, |
.mbist_si_i (mbist_si_i_internal), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
); |
|
`else // RAM blocks sharing between two fifos |
|
/*----------------------------------------------------------------------------------------------------------- |
Code section under this ifdef is used for implementation where RAM instances are too expensive. In this |
case one RAM instance is used for both - WISHBONE read and WISHBONE write fifo. |
-----------------------------------------------------------------------------------------------------------*/ |
/*----------------------------------------------------------------------------------------------------------- |
Address prefix definition - since both FIFOs reside in same RAM instance, storage is separated by MSB |
addresses. WISHBONE write fifo addresses are padded with zeros on the MSB side ( at least one address line |
must be used for this ), WISHBONE read fifo addresses are padded with ones on the right ( at least one ). |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(`WB_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH - 1):0] wbw_addr_prefix = {( `WB_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH){1'b0}} ; |
wire [(`WB_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH - 1):0] wbr_addr_prefix = {( `WB_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH){1'b1}} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Port A address generation for RAM instance. RAM instance must be full two port RAM - read and write capability |
on both sides. |
Port A is clocked by WISHBONE clock, DIA is input for wbw_fifo, DOA is output for wbr_fifo. |
Address is multiplexed so operation can be switched between fifos. Default is a read on port. |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] portA_addr = wbw_wallow ? {wbw_addr_prefix, wbw_waddr} : {wbr_addr_prefix, wbr_raddr} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Port B is clocked by PCI clock, DIB is input for wbr_fifo, DOB is output for wbw_fifo. |
Address is multiplexed so operation can be switched between fifos. Default is a read on port. |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] portB_addr = wbr_wallow ? {wbr_addr_prefix, wbr_waddr} : {wbw_addr_prefix, wbw_raddr} ; |
|
wire portA_enable = 1'b1 ; |
|
wire portB_enable = 1'b1 ; |
|
// instantiate RAM for these two fifos |
pci_wb_tpram #(`WB_FIFO_RAM_ADDR_LENGTH, 40) wbu_fifo_storage |
( |
// Generic synchronous two-port RAM interface |
.clk_a(wb_clock_in), |
.rst_a(reset_in), |
.ce_a(portA_enable), |
.we_a(wbw_wallow), |
.oe_a(1'b1), |
.addr_a(portA_addr), |
.di_a(dpram_portA_input), |
.do_a(dpram_portA_output), |
.clk_b(pci_clock_in), |
.rst_b(reset_in), |
.ce_b(portB_enable), |
.we_b(wbr_wallow), |
.oe_b(1'b1), |
.addr_b(portB_addr), |
.di_b(dpram_portB_input), |
.do_b(dpram_portB_output) |
|
`ifdef PCI_BIST |
, |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
); |
|
`endif |
|
/*----------------------------------------------------------------------------------------------------------- |
Instantiation of two control logic modules - one for WBW_FIFO and one for WBR_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
pci_wbw_fifo_control #(WBW_ADDR_LENGTH) wbw_fifo_ctrl |
( |
.rclock_in(pci_clock_in), |
.wclock_in(wb_clock_in), |
.renable_in(wbw_renable_in), |
.wenable_in(wbw_wenable_in), |
.reset_in(reset_in), |
// .flush_in(wbw_flush_in), |
.almost_full_out(wbw_almost_full_out), |
.full_out(wbw_full_out), |
.empty_out(wbw_empty), |
.waddr_out(wbw_waddr), |
.raddr_out(wbw_raddr), |
.rallow_out(wbw_rallow), |
.wallow_out(wbw_wallow) |
); |
|
pci_wbr_fifo_control #(WBR_ADDR_LENGTH) wbr_fifo_ctrl |
( .rclock_in(wb_clock_in), |
.wclock_in(pci_clock_in), |
.renable_in(wbr_renable_in), |
.wenable_in(wbr_wenable_in), |
.reset_in(reset_in), |
.flush_in(wbr_flush_in), |
.empty_out(wbr_empty), |
.waddr_out(wbr_waddr), |
.raddr_out(wbr_raddr), |
.rallow_out(wbr_rallow), |
.wallow_out(wbr_wallow) |
); |
|
|
// in and out transaction counters and grey codes |
reg [(WBW_ADDR_LENGTH-2):0] inGreyCount ; |
reg [(WBW_ADDR_LENGTH-2):0] outGreyCount ; |
wire [(WBW_ADDR_LENGTH-2):0] inNextGreyCount = {wbw_inTransactionCount[(WBW_ADDR_LENGTH-2)], wbw_inTransactionCount[(WBW_ADDR_LENGTH-2):1] ^ wbw_inTransactionCount[(WBW_ADDR_LENGTH-3):0]} ; |
wire [(WBW_ADDR_LENGTH-2):0] outNextGreyCount = {wbw_outTransactionCount[(WBW_ADDR_LENGTH-2)], wbw_outTransactionCount[(WBW_ADDR_LENGTH-2):1] ^ wbw_outTransactionCount[(WBW_ADDR_LENGTH-3):0]} ; |
|
// input transaction counter increment - when last data of transaction is written to fifo |
wire in_count_en = wbw_wallow && wbw_last_in ; |
|
// output transaction counter increment - when last data is on top of fifo and read from it |
wire out_count_en = wbw_renable_in && wbw_last_out ; |
|
// register holding grey coded count of incoming transactions |
always@(posedge wb_clock_in or posedge wbw_clear) |
begin |
if (wbw_clear) |
begin |
inGreyCount <= #`FF_DELAY 0 ; |
end |
else |
if (in_count_en) |
inGreyCount <= #`FF_DELAY inNextGreyCount ; |
end |
|
wire [(WBW_ADDR_LENGTH-2):0] pci_clk_sync_inGreyCount ; |
reg [(WBW_ADDR_LENGTH-2):0] pci_clk_inGreyCount ; |
pci_synchronizer_flop #((WBW_ADDR_LENGTH - 1), 0) i_synchronizer_reg_inGreyCount |
( |
.data_in (inGreyCount), |
.clk_out (pci_clock_in), |
.sync_data_out (pci_clk_sync_inGreyCount), |
.async_reset (wbw_clear) |
) ; |
|
always@(posedge pci_clock_in or posedge wbw_clear) |
begin |
if (wbw_clear) |
pci_clk_inGreyCount <= #`FF_DELAY 0 ; |
else |
pci_clk_inGreyCount <= # `FF_DELAY pci_clk_sync_inGreyCount ; |
end |
|
// register holding grey coded count of outgoing transactions |
always@(posedge pci_clock_in or posedge wbw_clear) |
begin |
if (wbw_clear) |
begin |
outGreyCount <= #`FF_DELAY 0 ; |
end |
else |
if (out_count_en) |
outGreyCount <= #`FF_DELAY outNextGreyCount ; |
end |
|
// incoming transactions counter |
always@(posedge wb_clock_in or posedge wbw_clear) |
begin |
if (wbw_clear) |
wbw_inTransactionCount <= #`FF_DELAY 1 ; |
else |
if (in_count_en) |
wbw_inTransactionCount <= #`FF_DELAY wbw_inTransactionCount + 1'b1 ; |
end |
|
// outgoing transactions counter |
always@(posedge pci_clock_in or posedge wbw_clear) |
begin |
if (wbw_clear) |
wbw_outTransactionCount <= 1 ; |
else |
if (out_count_en) |
wbw_outTransactionCount <= #`FF_DELAY wbw_outTransactionCount + 1'b1 ; |
end |
|
assign wbw_transaction_ready_out = pci_clk_inGreyCount != outGreyCount ; |
|
endmodule |
|
/verilog/pci_pciw_pcir_fifos.v
0,0 → 1,625
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pciw_pcir_fifos.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.5 2003/08/14 13:06:03 simons |
// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. |
// |
// Revision 1.4 2003/08/08 16:36:33 tadejm |
// Added 'three_left_out' to pci_pciw_fifo signaling three locations before full. Added comparison between current registered cbe and next unregistered cbe to signal wb_master whether it is allowed to performe burst or not. Due to this, I needed 'three_left_out' so that writing to pci_pciw_fifo can be registered, otherwise timing problems would occure. |
// |
// Revision 1.3 2003/03/26 13:16:18 mihad |
// Added the reset value parameter to the synchronizer flop module. |
// Added resets to all synchronizer flop instances. |
// Repaired initial sync value in fifos. |
// |
// Revision 1.2 2003/01/30 22:01:08 mihad |
// Updated synchronization in top level fifo modules. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.10 2002/10/18 03:36:37 tadejm |
// Changed wrong signal name mbist_sen into mbist_ctrl_i. |
// |
// Revision 1.9 2002/10/17 22:51:08 tadejm |
// Changed BIST signals for RAMs. |
// |
// Revision 1.8 2002/10/11 10:09:01 mihad |
// Added additional testcase and changed rst name in BIST to trst |
// |
// Revision 1.7 2002/10/08 17:17:06 mihad |
// Added BIST signals for RAMs. |
// |
// Revision 1.6 2002/09/30 16:03:04 mihad |
// Added meta flop module for easier meta stable FF identification during synthesis |
// |
// Revision 1.5 2002/09/25 15:53:52 mihad |
// Removed all logic from asynchronous reset network |
// |
// Revision 1.4 2002/03/05 11:53:47 mihad |
// Added some testcases, removed un-needed fifo signals |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_pciw_pcir_fifos |
( |
wb_clock_in, |
pci_clock_in, |
reset_in, |
pciw_wenable_in, |
pciw_addr_data_in, |
pciw_cbe_in, |
pciw_control_in, |
pciw_renable_in, |
pciw_addr_data_out, |
pciw_cbe_out, |
pciw_control_out, |
// pciw_flush_in, // not used |
pciw_three_left_out, |
pciw_two_left_out, |
pciw_almost_full_out, |
pciw_full_out, |
pciw_almost_empty_out, |
pciw_empty_out, |
pciw_transaction_ready_out, |
pcir_wenable_in, |
pcir_data_in, |
pcir_be_in, |
pcir_control_in, |
pcir_renable_in, |
pcir_data_out, |
pcir_be_out, |
pcir_control_out, |
pcir_flush_in, |
pcir_full_out, |
pcir_almost_empty_out, |
pcir_empty_out, |
pcir_transaction_ready_out |
|
`ifdef PCI_BIST |
, |
// debug chain signals |
mbist_si_i, // bist scan serial in |
mbist_so_o, // bist scan serial out |
mbist_ctrl_i // bist chain shift control |
`endif |
) ; |
|
/*----------------------------------------------------------------------------------------------------------- |
System inputs: |
wb_clock_in - WISHBONE bus clock |
pci_clock_in - PCI bus clock |
reset_in - reset from control logic |
-------------------------------------------------------------------------------------------------------------*/ |
input wb_clock_in, pci_clock_in, reset_in ; |
|
/*----------------------------------------------------------------------------------------------------------- |
PCI WRITE FIFO interface signals prefixed with pciw_ - FIFO is used for posted writes initiated by external |
PCI master through PCI target interface, traveling through FIFO and are completed on WISHBONE by |
WISHBONE master interface |
|
write enable signal: |
pciw_wenable_in = write enable input for PCIW_FIFO - driven by PCI TARGET interface |
|
data input signals: |
pciw_addr_data_in = data input - data from PCI bus - first entry of transaction is address others are data entries |
pciw_cbe_in = bus command/byte enable(~#BE[3:0]) input - first entry of transaction is bus command, other are byte enables |
pciw_control_in = control input - encoded control bus input |
|
read enable signal: |
pciw_renable_in = read enable input driven by WISHBONE master interface |
|
data output signals: |
pciw_addr_data_out = data output - data from PCI bus - first entry of transaction is address, others are data entries |
pciw_cbe_out = bus command/byte enable output - first entry of transaction is bus command, others are byte enables |
pciw_control_out = control input - encoded control bus input |
|
status signals - monitored by various resources in the core |
pciw_flush_in = flush signal input for PCIW_FIFO - when asserted, fifo is flushed(emptied) |
pciw_almost_full_out = almost full output from PCIW_FIFO |
pciw_full_out = full output from PCIW_FIFO |
pciw_almost_empty_out = almost empty output from PCIW_FIFO |
pciw_empty_out = empty output from PCIW_FIFO |
pciw_transaction_ready_out = output indicating that one complete transaction is waiting in PCIW_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
// input control and data |
input pciw_wenable_in ; |
input [31:0] pciw_addr_data_in ; |
input [3:0] pciw_cbe_in ; |
input [3:0] pciw_control_in ; |
|
// output control and data |
input pciw_renable_in ; |
output [31:0] pciw_addr_data_out ; |
output [3:0] pciw_cbe_out ; |
output [3:0] pciw_control_out ; |
|
// flush input |
//input pciw_flush_in ; // not used |
|
// status outputs |
output pciw_three_left_out ; |
output pciw_two_left_out ; |
output pciw_almost_full_out ; |
output pciw_full_out ; |
output pciw_almost_empty_out ; |
output pciw_empty_out ; |
output pciw_transaction_ready_out ; |
|
/*----------------------------------------------------------------------------------------------------------- |
PCI READ FIFO interface signals prefixed with pcir_ - FIFO is used for holding delayed read completions |
initiated by master on PCI bus and completed on WISHBONE bus, |
|
write enable signal: |
pcir_wenable_in = write enable input for PCIR_FIFO - driven by WISHBONE master interface |
|
data input signals: |
pcir_data_in = data input - data from WISHBONE bus - there is no address entry here, since address is stored in separate register |
pcir_be_in = byte enable(~SEL[3:0]) input - byte enables - same through one transaction |
pcir_control_in = control input - encoded control bus input |
|
read enable signal: |
pcir_renable_in = read enable input driven by PCI target interface |
|
data output signals: |
pcir_data_out = data output - data from WISHBONE bus |
pcir_be_out = byte enable output(~SEL) |
pcir_control_out = control output - encoded control bus output |
|
status signals - monitored by various resources in the core |
pcir_flush_in = flush signal input for PCIR_FIFO - when asserted, fifo is flushed(emptied) |
pcir full_out = full output from PCIR_FIFO |
pcir_almost_empty_out = almost empty output from PCIR_FIFO |
pcir_empty_out = empty output from PCIR_FIFO |
pcir_transaction_ready_out = output indicating that one complete transaction is waiting in PCIR_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
// input control and data |
input pcir_wenable_in ; |
input [31:0] pcir_data_in ; |
input [3:0] pcir_be_in ; |
input [3:0] pcir_control_in ; |
|
// output control and data |
input pcir_renable_in ; |
output [31:0] pcir_data_out ; |
output [3:0] pcir_be_out ; |
output [3:0] pcir_control_out ; |
|
// flush input |
input pcir_flush_in ; |
|
// status outputs |
output pcir_full_out ; |
output pcir_almost_empty_out ; |
output pcir_empty_out ; |
output pcir_transaction_ready_out ; |
|
`ifdef PCI_BIST |
/*----------------------------------------------------- |
BIST debug chain port signals |
-----------------------------------------------------*/ |
input mbist_si_i; // bist scan serial in |
output mbist_so_o; // bist scan serial out |
input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control |
`endif |
|
/*----------------------------------------------------------------------------------------------------------- |
Address length parameters: |
PCIW_DEPTH = defines PCIW_FIFO depth |
PCIR_DEPTH = defines PCIR_FIFO depth |
PCIW_ADDR_LENGTH = defines PCIW_FIFO's location address length - log2(PCIW_DEPTH) |
PCIR_ADDR_LENGTH = defines PCIR_FIFO's location address length - log2(PCIR_DEPTH) |
-----------------------------------------------------------------------------------------------------------*/ |
parameter PCIW_DEPTH = `PCIW_DEPTH ; |
parameter PCIW_ADDR_LENGTH = `PCIW_ADDR_LENGTH ; |
parameter PCIR_DEPTH = `PCIR_DEPTH ; |
parameter PCIR_ADDR_LENGTH = `PCIR_ADDR_LENGTH ; |
|
/*----------------------------------------------------------------------------------------------------------- |
pciw_wallow = PCIW_FIFO write allow wire - writes to FIFO are allowed when FIFO isn't full and write enable is 1 |
pciw_rallow = PCIW_FIFO read allow wire - reads from FIFO are allowed when FIFO isn't empty and read enable is 1 |
-----------------------------------------------------------------------------------------------------------*/ |
wire pciw_wallow ; |
wire pciw_rallow ; |
|
/*----------------------------------------------------------------------------------------------------------- |
pcir_wallow = PCIR_FIFO write allow wire - writes to FIFO are allowed when FIFO isn't full and write enable is 1 |
pcir_rallow = PCIR_FIFO read allow wire - reads from FIFO are allowed when FIFO isn't empty and read enable is 1 |
-----------------------------------------------------------------------------------------------------------*/ |
wire pcir_wallow ; |
wire pcir_rallow ; |
|
/*----------------------------------------------------------------------------------------------------------- |
wires for address port conections from PCIW_FIFO control logic to RAM blocks used for PCIW_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(PCIW_ADDR_LENGTH - 1):0] pciw_raddr ; |
wire [(PCIW_ADDR_LENGTH - 1):0] pciw_waddr ; |
|
/*----------------------------------------------------------------------------------------------------------- |
wires for address port conections from PCIR_FIFO control logic to RAM blocks used for PCIR_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(PCIR_ADDR_LENGTH - 1):0] pcir_raddr ; |
wire [(PCIR_ADDR_LENGTH - 1):0] pcir_waddr ; |
|
/*----------------------------------------------------------------------------------------------------------- |
PCIW_FIFO transaction counters: used to count incoming transactions and outgoing transactions. When number of |
input transactions is equal to number of output transactions, it means that there isn't any complete transaction |
currently present in the FIFO. |
-----------------------------------------------------------------------------------------------------------*/ |
reg [(PCIW_ADDR_LENGTH - 1):0] pciw_inTransactionCount ; |
reg [(PCIW_ADDR_LENGTH - 1):0] pciw_outTransactionCount ; |
|
/*----------------------------------------------------------------------------------------------------------- |
FlipFlops for indicating if complete delayed read completion is present in the FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
/*reg pcir_inTransactionCount ; |
reg pcir_outTransactionCount ;*/ |
/*----------------------------------------------------------------------------------------------------------- |
wires monitoring control bus. When control bus on a write transaction has a value of `LAST, it means that |
complete transaction is in the FIFO. When control bus on a read transaction has a value of `LAST, |
it means that there was one complete transaction taken out of FIFO. |
-----------------------------------------------------------------------------------------------------------*/ |
wire pciw_last_in = pciw_control_in[`LAST_CTRL_BIT] ; |
wire pciw_last_out = pciw_control_out[`LAST_CTRL_BIT] ; |
|
/*wire pcir_last_in = pcir_wallow && (pcir_control_in == `LAST) ; |
wire pcir_last_out = pcir_rallow && (pcir_control_out == `LAST) ;*/ |
|
wire pciw_empty ; |
wire pcir_empty ; |
|
assign pciw_empty_out = pciw_empty ; |
assign pcir_empty_out = pcir_empty ; |
|
// clear wires for clearing FFs and registers |
wire pciw_clear = reset_in /*|| pciw_flush_in*/ ; // PCIW_FIFO's clear signal - flush not used |
wire pcir_clear = reset_in /*|| pcir_flush_in*/ ; // PCIR_FIFO's clear signal - flush changed to synchronous op. |
|
/*----------------------------------------------------------------------------------------------------------- |
Definitions of wires for connecting RAM instances |
-----------------------------------------------------------------------------------------------------------*/ |
wire [39:0] dpram_portA_output ; |
wire [39:0] dpram_portB_output ; |
|
wire [39:0] dpram_portA_input = {pciw_control_in, pciw_cbe_in, pciw_addr_data_in} ; |
wire [39:0] dpram_portB_input = {pcir_control_in, pcir_be_in, pcir_data_in} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Fifo output assignments - each ram port provides data for different fifo |
-----------------------------------------------------------------------------------------------------------*/ |
assign pciw_control_out = dpram_portB_output[39:36] ; |
assign pcir_control_out = dpram_portA_output[39:36] ; |
|
assign pciw_cbe_out = dpram_portB_output[35:32] ; |
assign pcir_be_out = dpram_portA_output[35:32] ; |
|
assign pciw_addr_data_out = dpram_portB_output[31:0] ; |
assign pcir_data_out = dpram_portA_output[31:0] ; |
|
`ifdef PCI_RAM_DONT_SHARE |
|
/*----------------------------------------------------------------------------------------------------------- |
Piece of code in this ifdef section is used in applications which can provide enough RAM instances to |
accomodate four fifos - each occupying its own instance of ram. Ports are connected in such a way, |
that instances of RAMs can be changed from two port to dual port ( async read/write port ). In that case, |
write port is always port a and read port is port b. |
-----------------------------------------------------------------------------------------------------------*/ |
|
/*----------------------------------------------------------------------------------------------------------- |
Pad redundant address lines with zeros. This may seem stupid, but it comes in perfect for FPGA impl. |
-----------------------------------------------------------------------------------------------------------*/ |
/* |
wire [(`PCIW_FIFO_RAM_ADDR_LENGTH - PCIW_ADDR_LENGTH - 1):0] pciw_addr_prefix = {( `PCIW_FIFO_RAM_ADDR_LENGTH - PCIW_ADDR_LENGTH){1'b0}} ; |
wire [(`PCIR_FIFO_RAM_ADDR_LENGTH - PCIR_ADDR_LENGTH - 1):0] pcir_addr_prefix = {( `PCIR_FIFO_RAM_ADDR_LENGTH - PCIR_ADDR_LENGTH){1'b0}} ; |
*/ |
|
// compose complete port addresses |
wire [(`PCI_FIFO_RAM_ADDR_LENGTH-1):0] pciw_whole_waddr = pciw_waddr ; |
wire [(`PCI_FIFO_RAM_ADDR_LENGTH-1):0] pciw_whole_raddr = pciw_raddr ; |
|
wire [(`PCI_FIFO_RAM_ADDR_LENGTH-1):0] pcir_whole_waddr = pcir_waddr ; |
wire [(`PCI_FIFO_RAM_ADDR_LENGTH-1):0] pcir_whole_raddr = pcir_raddr ; |
|
wire pciw_read_enable = 1'b1 ; |
wire pcir_read_enable = 1'b1 ; |
|
`ifdef PCI_BIST |
wire mbist_so_o_internal ; // wires for connection of debug ports on two rams |
wire mbist_si_i_internal = mbist_so_o_internal ; |
`endif |
|
// instantiate and connect two generic rams - one for pci write fifo and one for pci read fifo |
pci_pci_tpram #(`PCI_FIFO_RAM_ADDR_LENGTH, 40) pciw_fifo_storage |
( |
// Generic synchronous two-port RAM interface |
.clk_a(pci_clock_in), |
.rst_a(reset_in), |
.ce_a(1'b1), |
.we_a(pciw_wallow), |
.oe_a(1'b1), |
.addr_a(pciw_whole_waddr), |
.di_a(dpram_portA_input), |
.do_a(), |
|
.clk_b(wb_clock_in), |
.rst_b(reset_in), |
.ce_b(pciw_read_enable), |
.we_b(1'b0), |
.oe_b(1'b1), |
.addr_b(pciw_whole_raddr), |
.di_b(40'h00_0000_0000), |
.do_b(dpram_portB_output) |
|
`ifdef PCI_BIST |
, |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o_internal), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
); |
|
pci_pci_tpram #(`PCI_FIFO_RAM_ADDR_LENGTH, 40) pcir_fifo_storage |
( |
// Generic synchronous two-port RAM interface |
.clk_a(wb_clock_in), |
.rst_a(reset_in), |
.ce_a(1'b1), |
.we_a(pcir_wallow), |
.oe_a(1'b1), |
.addr_a(pcir_whole_waddr), |
.di_a(dpram_portB_input), |
.do_a(), |
|
.clk_b(pci_clock_in), |
.rst_b(reset_in), |
.ce_b(pcir_read_enable), |
.we_b(1'b0), |
.oe_b(1'b1), |
.addr_b(pcir_whole_raddr), |
.di_b(40'h00_0000_0000), |
.do_b(dpram_portA_output) |
|
`ifdef PCI_BIST |
, |
.mbist_si_i (mbist_si_i_internal), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
); |
|
`else // RAM blocks sharing between two fifos |
|
/*----------------------------------------------------------------------------------------------------------- |
Code section under this ifdef is used for implementation where RAM instances are too expensive. In this |
case one RAM instance is used for both - pci read and pci write fifo. |
-----------------------------------------------------------------------------------------------------------*/ |
/*----------------------------------------------------------------------------------------------------------- |
Address prefix definition - since both FIFOs reside in same RAM instance, storage is separated by MSB |
addresses. pci write fifo addresses are padded with zeros on the MSB side ( at least one address line |
must be used for this ), pci read fifo addresses are padded with ones on the right ( at least one ). |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(`PCI_FIFO_RAM_ADDR_LENGTH - PCIW_ADDR_LENGTH - 1):0] pciw_addr_prefix = {( `PCI_FIFO_RAM_ADDR_LENGTH - PCIW_ADDR_LENGTH){1'b0}} ; |
wire [(`PCI_FIFO_RAM_ADDR_LENGTH - PCIR_ADDR_LENGTH - 1):0] pcir_addr_prefix = {( `PCI_FIFO_RAM_ADDR_LENGTH - PCIR_ADDR_LENGTH){1'b1}} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Port A address generation for RAM instance. RAM instance must be full two port RAM - read and write capability |
on both sides. |
Port A is clocked by PCI clock, DIA is input for pciw_fifo, DOA is output for pcir_fifo. |
Address is multiplexed so operation can be switched between fifos. Default is a read on port. |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(`PCI_FIFO_RAM_ADDR_LENGTH-1):0] portA_addr = pciw_wallow ? {pciw_addr_prefix, pciw_waddr} : {pcir_addr_prefix, pcir_raddr} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Port B is clocked by WISHBONE clock, DIB is input for pcir_fifo, DOB is output for pciw_fifo. |
Address is multiplexed so operation can be switched between fifos. Default is a read on port. |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(`PCI_FIFO_RAM_ADDR_LENGTH-1):0] portB_addr = pcir_wallow ? {pcir_addr_prefix, pcir_waddr} : {pciw_addr_prefix, pciw_raddr} ; |
|
wire portA_enable = 1'b1 ; |
|
wire portB_enable = 1'b1 ; |
|
// instantiate RAM for these two fifos |
pci_pci_tpram #(`PCI_FIFO_RAM_ADDR_LENGTH, 40) pciu_fifo_storage |
( |
// Generic synchronous two-port RAM interface |
.clk_a(pci_clock_in), |
.rst_a(reset_in), |
.ce_a(portA_enable), |
.we_a(pciw_wallow), |
.oe_a(1'b1), |
.addr_a(portA_addr), |
.di_a(dpram_portA_input), |
.do_a(dpram_portA_output), |
.clk_b(wb_clock_in), |
.rst_b(reset_in), |
.ce_b(portB_enable), |
.we_b(pcir_wallow), |
.oe_b(1'b1), |
.addr_b(portB_addr), |
.di_b(dpram_portB_input), |
.do_b(dpram_portB_output) |
|
`ifdef PCI_BIST |
, |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
); |
|
`endif |
|
/*----------------------------------------------------------------------------------------------------------- |
Instantiation of two control logic modules - one for PCIW_FIFO and one for PCIR_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
pci_pciw_fifo_control #(PCIW_ADDR_LENGTH) pciw_fifo_ctrl |
( |
.rclock_in(wb_clock_in), |
.wclock_in(pci_clock_in), |
.renable_in(pciw_renable_in), |
.wenable_in(pciw_wenable_in), |
.reset_in(reset_in), |
// .flush_in(pciw_flush_in), // flush not used |
.three_left_out(pciw_three_left_out), |
.two_left_out(pciw_two_left_out), |
.almost_full_out(pciw_almost_full_out), |
.full_out(pciw_full_out), |
.almost_empty_out(pciw_almost_empty_out), |
.empty_out(pciw_empty), |
.waddr_out(pciw_waddr), |
.raddr_out(pciw_raddr), |
.rallow_out(pciw_rallow), |
.wallow_out(pciw_wallow) |
); |
|
pci_pcir_fifo_control #(PCIR_ADDR_LENGTH) pcir_fifo_ctrl |
( |
.rclock_in(pci_clock_in), |
.wclock_in(wb_clock_in), |
.renable_in(pcir_renable_in), |
.wenable_in(pcir_wenable_in), |
.reset_in(reset_in), |
.flush_in(pcir_flush_in), |
.full_out(pcir_full_out), |
.almost_empty_out(pcir_almost_empty_out), |
.empty_out(pcir_empty), |
.waddr_out(pcir_waddr), |
.raddr_out(pcir_raddr), |
.rallow_out(pcir_rallow), |
.wallow_out(pcir_wallow) |
); |
|
|
// in and out transaction counters and grey codes |
reg [(PCIW_ADDR_LENGTH-2):0] inGreyCount ; |
reg [(PCIW_ADDR_LENGTH-2):0] outGreyCount ; |
wire [(PCIW_ADDR_LENGTH-2):0] inNextGreyCount = {pciw_inTransactionCount[(PCIW_ADDR_LENGTH-2)], pciw_inTransactionCount[(PCIW_ADDR_LENGTH-2):1] ^ pciw_inTransactionCount[(PCIW_ADDR_LENGTH-3):0]} ; |
wire [(PCIW_ADDR_LENGTH-2):0] outNextGreyCount = {pciw_outTransactionCount[(PCIW_ADDR_LENGTH-2)], pciw_outTransactionCount[(PCIW_ADDR_LENGTH-2):1] ^ pciw_outTransactionCount[(PCIW_ADDR_LENGTH-3):0]} ; |
|
// input transaction counter is incremented when whole transaction is written to fifo. This is indicated by last control bit written to last transaction location |
wire in_count_en = pciw_wallow && pciw_last_in ; |
|
// output transaction counter is incremented when whole transaction is pulled out of fifo. This is indicated when location with last control bit set is read |
wire out_count_en = pciw_rallow && pciw_last_out ; |
|
always@(posedge pci_clock_in or posedge pciw_clear) |
begin |
if (pciw_clear) |
begin |
inGreyCount <= 0 ; |
end |
else |
if (in_count_en) |
inGreyCount <= #`FF_DELAY inNextGreyCount ; |
end |
|
wire [(PCIW_ADDR_LENGTH-2):0] wb_clk_sync_inGreyCount ; |
reg [(PCIW_ADDR_LENGTH-2):0] wb_clk_inGreyCount ; |
pci_synchronizer_flop #((PCIW_ADDR_LENGTH - 1), 0) i_synchronizer_reg_inGreyCount |
( |
.data_in (inGreyCount), |
.clk_out (wb_clock_in), |
.sync_data_out (wb_clk_sync_inGreyCount), |
.async_reset (pciw_clear) |
) ; |
|
always@(posedge wb_clock_in or posedge pciw_clear) |
begin |
if (pciw_clear) |
wb_clk_inGreyCount <= #`FF_DELAY 0 ; |
else |
wb_clk_inGreyCount <= # `FF_DELAY wb_clk_sync_inGreyCount ; |
end |
|
always@(posedge wb_clock_in or posedge pciw_clear) |
begin |
if (pciw_clear) |
begin |
outGreyCount <= #`FF_DELAY 0 ; |
end |
else |
if (out_count_en) |
outGreyCount <= #`FF_DELAY outNextGreyCount ; |
end |
|
always@(posedge pci_clock_in or posedge pciw_clear) |
begin |
if (pciw_clear) |
pciw_inTransactionCount <= #`FF_DELAY 1 ; |
else |
if (in_count_en) |
pciw_inTransactionCount <= #`FF_DELAY pciw_inTransactionCount + 1'b1 ; |
end |
|
always@(posedge wb_clock_in or posedge pciw_clear) |
begin |
if (pciw_clear) |
pciw_outTransactionCount <= #`FF_DELAY 1 ; |
else |
if (out_count_en) |
pciw_outTransactionCount <= #`FF_DELAY pciw_outTransactionCount + 1'b1 ; |
end |
|
assign pciw_transaction_ready_out = wb_clk_inGreyCount != outGreyCount ; |
|
assign pcir_transaction_ready_out = 1'b0 ; |
|
endmodule |
|
/verilog/pci_target32_interface.v
0,0 → 1,939
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_target32_interface.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.8 2003/08/08 16:36:33 tadejm |
// Added 'three_left_out' to pci_pciw_fifo signaling three locations before full. Added comparison between current registered cbe and next unregistered cbe to signal wb_master whether it is allowed to performe burst or not. Due to this, I needed 'three_left_out' so that writing to pci_pciw_fifo can be registered, otherwise timing problems would occure. |
// |
// Revision 1.7 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.6 2003/01/21 16:06:56 mihad |
// Bug fixes, testcases added. |
// |
// Revision 1.5 2002/08/22 13:28:04 mihad |
// Updated for synthesis purposes. Gate level simulation was failing in some configurations |
// |
// Revision 1.4 2002/02/19 16:32:37 mihad |
// Modified testbench and fixed some bugs |
// |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`include "bus_commands.v" |
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_target32_interface |
( |
// system inputs |
clk_in, |
reset_in, |
|
// PCI Target side of INTERFACE |
address_in, |
addr_claim_out, |
bc_in, |
bc0_in, |
data_in, |
data_out, |
be_in, |
next_be_in, |
req_in, |
rdy_in, |
addr_phase_in, |
bckp_devsel_in, |
bckp_trdy_in, |
bckp_stop_in, |
last_reg_in, |
frame_reg_in, |
fetch_pcir_fifo_in, |
load_medium_reg_in, |
sel_fifo_mreg_in, |
sel_conf_fifo_in, |
fetch_conf_in, |
load_to_pciw_fifo_in, |
load_to_conf_in, |
same_read_out, |
|
norm_access_to_config_out, |
read_completed_out, |
read_processing_out, |
target_abort_out, |
disconect_wo_data_out, |
disconect_w_data_out, |
pciw_fifo_full_out, |
pcir_fifo_data_err_out, |
wbw_fifo_empty_out, |
wbu_del_read_comp_pending_out, |
|
// Delayed synchronizacion module signals |
req_out, |
done_out, |
in_progress_out, |
req_req_pending_in, |
req_comp_pending_in, |
addr_out, |
be_out, |
we_out, |
bc_out, |
burst_ok_out, |
strd_addr_in, |
strd_bc_in, |
status_in, |
comp_flush_in, |
|
// FIFO signals |
pcir_fifo_renable_out, |
pcir_fifo_data_in, |
pcir_fifo_be_in, |
pcir_fifo_control_in, |
pcir_fifo_flush_out, |
pcir_fifo_almost_empty_in, |
pcir_fifo_empty_in, |
pciw_fifo_wenable_out, |
pciw_fifo_addr_data_out, |
pciw_fifo_cbe_out, |
pciw_fifo_control_out, |
pciw_fifo_three_left_in, |
pciw_fifo_two_left_in, |
pciw_fifo_almost_full_in, |
pciw_fifo_full_in, |
wbw_fifo_empty_in, |
wbu_del_read_comp_pending_in, |
|
// Configuration space signals |
conf_hit_out, |
conf_addr_out, |
conf_data_out, |
conf_data_in, |
conf_be_out, |
conf_we_out, |
conf_re_out, |
mem_enable_in, |
io_enable_in, |
mem_io_addr_space0_in, |
mem_io_addr_space1_in, |
mem_io_addr_space2_in, |
mem_io_addr_space3_in, |
mem_io_addr_space4_in, |
mem_io_addr_space5_in, |
pre_fetch_en0_in, |
pre_fetch_en1_in, |
pre_fetch_en2_in, |
pre_fetch_en3_in, |
pre_fetch_en4_in, |
pre_fetch_en5_in, |
pci_base_addr0_in, |
pci_base_addr1_in, |
pci_base_addr2_in, |
pci_base_addr3_in, |
pci_base_addr4_in, |
pci_base_addr5_in, |
pci_addr_mask0_in, |
pci_addr_mask1_in, |
pci_addr_mask2_in, |
pci_addr_mask3_in, |
pci_addr_mask4_in, |
pci_addr_mask5_in, |
pci_tran_addr0_in, |
pci_tran_addr1_in, |
pci_tran_addr2_in, |
pci_tran_addr3_in, |
pci_tran_addr4_in, |
pci_tran_addr5_in, |
addr_tran_en0_in, |
addr_tran_en1_in, |
addr_tran_en2_in, |
addr_tran_en3_in, |
addr_tran_en4_in, |
addr_tran_en5_in |
) ; |
|
/*================================================================================================================== |
System inputs. |
==================================================================================================================*/ |
// PCI side clock and reset |
input clk_in, |
reset_in ; |
|
|
/*================================================================================================================== |
Side of the PCI Target state machine |
==================================================================================================================*/ |
// Data, byte enables, bus commands and address ports |
input [31:0] address_in ; // current request address input - registered |
output addr_claim_out ; // current request address claim output |
input [3:0] bc_in ; // current request bus command input - registered |
input bc0_in ; // current cycle RW signal |
output [31:0] data_out ; // for read operations - current dataphase data output |
input [31:0] data_in ; // for write operations - current request data input - registered |
input [3:0] be_in ; // current dataphase byte enable inputs - registered |
input [3:0] next_be_in ; // next dataphase byte enable inputs - NOT registered |
// Port connection control signals from PCI FSM |
input req_in ; // Read is requested to WB master from PCI side |
input rdy_in ; // DATA / ADDRESS selection from PCI side when read or write - registered |
input addr_phase_in ; // Indicates address phase and also fast-back-to-back address phase - registered |
input bckp_devsel_in ; // DEVSEL input (which is registered) equivalent |
input bckp_trdy_in ; // TRDY input (which is registered) equivalent |
input bckp_stop_in ; // STOP input (which is registered) equivalent |
input last_reg_in ; // Indicates last data phase - registered |
input frame_reg_in ; // FRAME input signal - registered |
input fetch_pcir_fifo_in ;// Read enable for PCIR_FIFO when when read is finishen on WB side |
input load_medium_reg_in ;// Load data from PCIR_FIFO to medium register (first data must be prepared on time) |
input sel_fifo_mreg_in ; // Read data selection between PCIR_FIFO and medium register |
input sel_conf_fifo_in ; // Read data selection between Configuration registers and "FIFO" |
input fetch_conf_in ; // Read enable for configuration space registers |
input load_to_pciw_fifo_in ;// Write enable to PCIW_FIFO |
input load_to_conf_in ; // Write enable to Configuration space registers |
|
|
/*================================================================================================================== |
Status outputs to PCI side (FSM) |
==================================================================================================================*/ |
output same_read_out ; // Indicates the same read request (important when read is finished on WB side) |
output norm_access_to_config_out ; // Indicates the access to Configuration space with MEMORY commands |
output read_completed_out ; // Indicates that read request is completed on WB side |
output read_processing_out ; // Indicates that read request is processing on WB side |
output target_abort_out ; // Indicates target abort termination |
output disconect_wo_data_out ; // Indicates disconnect without data termination |
output disconect_w_data_out ; // Indicates disconnect with data termination |
output pciw_fifo_full_out ; // Indicates that write PCIW_FIFO is full |
output pcir_fifo_data_err_out ; // Indicates data error on current data read from PCIR_FIFO |
output wbw_fifo_empty_out ; // Indicates that WB SLAVE has no data to be written to PCI bus |
output wbu_del_read_comp_pending_out ; // Indicates that WB Unit has a delayed read poending! |
|
/*================================================================================================================== |
Read request interface through Delayed sinchronization module to WB Master |
==================================================================================================================*/ |
// request, completion, done and progress indicator outputs for delayed_sync module where they are synchronized |
output req_out, // request qualifier - when 1 it indicates that valid data is provided on outputs |
done_out, // done output - when 1 indicates that PCI Target has completed a cycle on its bus |
in_progress_out ; // out progress indicator - indicates that current completion is in progress on |
// PCI Target side |
// pending indication inputs - PCI Target side must know about requests and completions |
input req_req_pending_in ; // request pending input for PCI Target side |
input req_comp_pending_in ; // completion pending input for PCI Target side - it indicates when completion |
// is ready for completing on PCI Target bus |
// various data outputs - PCI Target sets address, bus command, byte enables, write enable and burst |
output [31:0] addr_out ; // address bus output |
output [3:0] be_out ; // byte enable output |
output we_out ; // write enable output - read/write request indication 1 = write request / 0 = read request |
output [3:0] bc_out ; // bus command output |
output burst_ok_out ; // pre-fetch enable & burst read - qualifies pre-fetch for access to current image space |
|
// completion side signals encoded termination status - 0 = normal completion / 1 = error terminated completion |
input [31:0] strd_addr_in ; // Stored requested read access address |
input [3:0] strd_bc_in ; // Stored requested read access bus command |
input status_in ; // Error status reported - NOT USED because FIFO control bits determin data error status |
input comp_flush_in ; // If completition counter (2^16 clk periods) has expired, PCIR_FIFO must flush data |
|
|
/*================================================================================================================== |
PCIR_PCIW_FIFO signals from pci side |
==================================================================================================================*/ |
// PCIR_FIFO control signals used for fetching data from PCIR_FIFO |
output pcir_fifo_renable_out ; // read enable output to PCIR_FIFO |
input [31:0] pcir_fifo_data_in ; // data input from PCIR_FIFO |
input [3:0] pcir_fifo_be_in ; // byte enable input from PCIR_FIFO |
input [3:0] pcir_fifo_control_in ; // control signals input from PCIR_FIFO |
output pcir_fifo_flush_out ; // flush PCIR_FIFO |
input pcir_fifo_almost_empty_in ; // almost empty indicator from PCIR_FIFO |
input pcir_fifo_empty_in ; // empty indicator |
|
// PCIW_FIFO control signals used for sinking data into PCIW_FIFO and status monitoring |
output pciw_fifo_wenable_out ; // write enable output to PCIW_FIFO |
wire pciw_fifo_wenable ; // not registered we |
output [31:0] pciw_fifo_addr_data_out ; // address / data output signals to PCIW_FIFO |
output [3:0] pciw_fifo_cbe_out ; // command / byte enable signals to PCIW_FIFO |
output [3:0] pciw_fifo_control_out ; // control signals to PCIW_FIFO |
input pciw_fifo_three_left_in ; // three data spaces left in PCIW_FIFO |
input pciw_fifo_two_left_in ; // two data spaces left in PCIW_FIFO |
input pciw_fifo_almost_full_in ; // almost full indicator from PCIW_FIFO |
input pciw_fifo_full_in ; // full indicator from PCIW_FIFO |
|
// WBW_FIFO empy control signal used when delayed read is complete in PCIR_FIFO |
input wbw_fifo_empty_in ; // empty indicator from WBW_FIFO |
input wbu_del_read_comp_pending_in ; // delayed read pending indicator from WB Unit |
|
|
/*================================================================================================================== |
Configuration space signals - from and to registers |
==================================================================================================================*/ |
// BUS for reading and writing to configuration space registers |
output conf_hit_out ; // like "chip select" for configuration space |
output [11:0] conf_addr_out ; // address to configuration space when there is access to it |
output [31:0] conf_data_out ; // data to configuration space - for writing to registers |
input [31:0] conf_data_in ; // data from configuration space - for reading from registers |
output [3:0] conf_be_out ; // byte enables used for correct writing to configuration space |
output conf_we_out ; // write enable control signal - 1 for writing / 0 for nothing |
output conf_re_out ; // read enable control signal - 1 for reading / 0 for nothing |
|
// Inputs for image control registers |
input mem_enable_in ; // allowed access to memory mapped image |
input io_enable_in ; // allowed access to io mapped image |
|
// Inputs needed for determining if image is assigned to memory or io space with pre-fetch and address translation |
input mem_io_addr_space0_in ; // bit-0 in pci_base_addr0 register |
input mem_io_addr_space1_in ; // bit-0 in pci_base_addr1 register |
input mem_io_addr_space2_in ; // bit-0 in pci_base_addr2 register |
input mem_io_addr_space3_in ; // bit-0 in pci_base_addr3 register |
input mem_io_addr_space4_in ; // bit-0 in pci_base_addr4 register |
input mem_io_addr_space5_in ; // bit-0 in pci_base_addr5 register |
input pre_fetch_en0_in ; // bit-1 in pci_image_ctr0 register |
input pre_fetch_en1_in ; // bit-1 in pci_image_ctr1 register |
input pre_fetch_en2_in ; // bit-1 in pci_image_ctr2 register |
input pre_fetch_en3_in ; // bit-1 in pci_image_ctr3 register |
input pre_fetch_en4_in ; // bit-1 in pci_image_ctr4 register |
input pre_fetch_en5_in ; // bit-1 in pci_image_ctr5 register |
|
// Input from image registers - register values needed for decoder to work properly |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr0_in ; // base address from base address register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr1_in ; // base address from base address register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr2_in ; // base address from base address register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr3_in ; // base address from base address register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr4_in ; // base address from base address register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr5_in ; // base address from base address register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask0_in ; // masking of base address from address mask register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask1_in ; // masking of base address from address mask register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask2_in ; // masking of base address from address mask register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask3_in ; // masking of base address from address mask register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask4_in ; // masking of base address from address mask register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask5_in ; // masking of base address from address mask register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr0_in ; // translation address from address translation register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr1_in ; // translation address from address translation register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr2_in ; // translation address from address translation register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr3_in ; // translation address from address translation register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr4_in ; // translation address from address translation register |
input [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr5_in ; // translation address from address translation register |
|
input addr_tran_en0_in ; // address translation enable bit |
input addr_tran_en1_in ; // address translation enable bit |
input addr_tran_en2_in ; // address translation enable bit |
input addr_tran_en3_in ; // address translation enable bit |
input addr_tran_en4_in ; // address translation enable bit |
input addr_tran_en5_in ; // address translation enable bit |
|
/*================================================================================================================== |
END of input / output PORT DEFINITONS !!! |
==================================================================================================================*/ |
|
// address output from address multiplexer |
reg [31:0] address ; |
// prefetch enable for access to selected image space |
reg pre_fetch_en ; |
|
// Input addresses and image hits from address decoders - addresses are multiplexed to address |
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
`ifdef PCI_IMAGE0 // if PCI bridge is HOST and IMAGE0 is assigned as general image space |
wire hit0_in ; |
wire [31:0] address0_in ; |
wire pre_fetch_en0 = pre_fetch_en0_in ; |
`else |
wire hit0_in = 1'b0 ; |
wire [31:0] address0_in = 32'h0 ; |
wire pre_fetch_en0 = 1'b0 ; |
`endif |
`else |
wire hit0_in ; |
wire [31:0] address0_in ; |
wire pre_fetch_en0 = pre_fetch_en0_in ; |
`endif |
`else // GUEST |
wire hit0_in ; |
wire [31:0] address0_in ; |
wire pre_fetch_en0 = pre_fetch_en0_in ; |
`endif |
|
wire hit1_in ; |
wire [31:0] address1_in ; |
wire pre_fetch_en1 = pre_fetch_en1_in ; |
|
`ifdef PCI_IMAGE2 |
wire hit2_in ; |
wire [31:0] address2_in ; |
wire pre_fetch_en2 = pre_fetch_en2_in ; |
`else |
wire hit2_in = 1'b0 ; |
wire [31:0] address2_in = 32'h0 ; |
wire pre_fetch_en2 = 1'b0 ; |
`endif |
|
`ifdef PCI_IMAGE3 |
wire hit3_in ; |
wire [31:0] address3_in ; |
wire pre_fetch_en3 = pre_fetch_en3_in ; |
`else |
wire hit3_in = 1'b0 ; |
wire [31:0] address3_in = 32'h0 ; |
wire pre_fetch_en3 = 1'b0 ; |
`endif |
|
`ifdef PCI_IMAGE4 |
wire hit4_in ; |
wire [31:0] address4_in ; |
wire pre_fetch_en4 = pre_fetch_en4_in ; |
`else |
wire hit4_in = 1'b0 ; |
wire [31:0] address4_in = 32'h0 ; |
wire pre_fetch_en4 = 1'b0 ; |
`endif |
|
`ifdef PCI_IMAGE5 |
wire hit5_in ; |
wire [31:0] address5_in ; |
wire pre_fetch_en5 = pre_fetch_en5_in ; |
`else |
wire hit5_in = 1'b0 ; |
wire [31:0] address5_in = 32'h0 ; |
wire pre_fetch_en5 = 1'b0 ; |
`endif |
|
// Include address decoders |
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
`ifdef PCI_IMAGE0 // if PCI bridge is HOST and IMAGE0 is assigned as general image space |
pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder0 |
(.hit (hit0_in), |
.addr_out (address0_in), |
.addr_in (address_in), |
.bc_in (bc_in), |
.base_addr (pci_base_addr0_in), |
.mask_addr (pci_addr_mask0_in), |
.tran_addr (pci_tran_addr0_in), |
.at_en (addr_tran_en0_in), |
.mem_io_space (mem_io_addr_space0_in), |
.mem_en (mem_enable_in), |
.io_en (io_enable_in) |
) ; |
`endif |
`else |
pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder0 |
(.hit (hit0_in), |
.addr_out (address0_in), |
.addr_in (address_in), |
.bc_in (bc_in), |
.base_addr (pci_base_addr0_in), |
.mask_addr (pci_addr_mask0_in), |
.tran_addr (pci_tran_addr0_in), |
.at_en (addr_tran_en0_in), |
.mem_io_space (mem_io_addr_space0_in), |
.mem_en (mem_enable_in), |
.io_en (io_enable_in) |
) ; |
`endif |
`else // GUEST |
pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder0 |
(.hit (hit0_in), |
.addr_out (address0_in), |
.addr_in (address_in), |
.bc_in (bc_in), |
.base_addr (pci_base_addr0_in), |
.mask_addr (pci_addr_mask0_in), |
.tran_addr (pci_tran_addr0_in), |
.at_en (addr_tran_en0_in), |
.mem_io_space (mem_io_addr_space0_in), |
.mem_en (mem_enable_in), |
.io_en (io_enable_in) |
) ; |
`endif |
pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder1 |
(.hit (hit1_in), |
.addr_out (address1_in), |
.addr_in (address_in), |
.bc_in (bc_in), |
.base_addr (pci_base_addr1_in), |
.mask_addr (pci_addr_mask1_in), |
.tran_addr (pci_tran_addr1_in), |
.at_en (addr_tran_en1_in), |
.mem_io_space (mem_io_addr_space1_in), |
.mem_en (mem_enable_in), |
.io_en (io_enable_in) |
) ; |
`ifdef PCI_IMAGE2 |
pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder2 |
(.hit (hit2_in), |
.addr_out (address2_in), |
.addr_in (address_in), |
.bc_in (bc_in), |
.base_addr (pci_base_addr2_in), |
.mask_addr (pci_addr_mask2_in), |
.tran_addr (pci_tran_addr2_in), |
.at_en (addr_tran_en2_in), |
.mem_io_space (mem_io_addr_space2_in), |
.mem_en (mem_enable_in), |
.io_en (io_enable_in) |
) ; |
`endif |
`ifdef PCI_IMAGE3 |
pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder3 |
(.hit (hit3_in), |
.addr_out (address3_in), |
.addr_in (address_in), |
.bc_in (bc_in), |
.base_addr (pci_base_addr3_in), |
.mask_addr (pci_addr_mask3_in), |
.tran_addr (pci_tran_addr3_in), |
.at_en (addr_tran_en3_in), |
.mem_io_space (mem_io_addr_space3_in), |
.mem_en (mem_enable_in), |
.io_en (io_enable_in) |
) ; |
`endif |
`ifdef PCI_IMAGE4 |
pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder4 |
(.hit (hit4_in), |
.addr_out (address4_in), |
.addr_in (address_in), |
.bc_in (bc_in), |
.base_addr (pci_base_addr4_in), |
.mask_addr (pci_addr_mask4_in), |
.tran_addr (pci_tran_addr4_in), |
.at_en (addr_tran_en4_in), |
.mem_io_space (mem_io_addr_space4_in), |
.mem_en (mem_enable_in), |
.io_en (io_enable_in) |
) ; |
`endif |
`ifdef PCI_IMAGE5 |
pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder5 |
(.hit (hit5_in), |
.addr_out (address5_in), |
.addr_in (address_in), |
.bc_in (bc_in), |
.base_addr (pci_base_addr5_in), |
.mask_addr (pci_addr_mask5_in), |
.tran_addr (pci_tran_addr5_in), |
.at_en (addr_tran_en5_in), |
.mem_io_space (mem_io_addr_space5_in), |
.mem_en (mem_enable_in), |
.io_en (io_enable_in) |
) ; |
`endif |
|
// Internal signals for image hit determination |
reg addr_claim ;// address claim signal is asinchronous set for addr_claim_out signal to PCI Target SM |
|
// Determining if image 0 is assigned to configuration space or as normal pci to wb access! |
// if normal access is allowed to configuration space, then hit0 is hit0_conf |
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
parameter hit0_conf = 1'b0 ; |
`else |
parameter hit0_conf = 1'b1 ; // if normal access is allowed to configuration space, then hit0 is hit0_conf |
`endif |
`else // GUEST |
parameter hit0_conf = 1'b1 ; // if normal access is allowed to configuration space, then hit0 is hit0_conf |
`endif |
|
// Logic with address mux, determining if address is still in the same image space and if it is prefetced or not |
always@(hit5_in or hit4_in or hit3_in or hit2_in or hit1_in or hit0_in or |
address5_in or address4_in or address3_in or address2_in or address1_in or address0_in or |
pre_fetch_en5 or |
pre_fetch_en4 or |
pre_fetch_en3 or |
pre_fetch_en2 or |
pre_fetch_en1 or |
pre_fetch_en0 |
) |
begin |
addr_claim <= (hit5_in || hit4_in) || (hit3_in || hit2_in || hit1_in || hit0_in) ; |
case ({hit5_in, hit4_in, hit3_in, hit2_in, hit0_in}) |
5'b10000 : |
begin |
address <= address5_in ; |
pre_fetch_en <= pre_fetch_en5 ; |
end |
5'b01000 : |
begin |
address <= address4_in ; |
pre_fetch_en <= pre_fetch_en4 ; |
end |
5'b00100 : |
begin |
address <= address3_in ; |
pre_fetch_en <= pre_fetch_en3 ; |
end |
5'b00010 : |
begin |
address <= address2_in ; |
pre_fetch_en <= pre_fetch_en2 ; |
end |
5'b00001 : |
begin |
address <= address0_in ; |
pre_fetch_en <= pre_fetch_en0 ; |
end |
default : // IMAGE 1 is always included into PCI bridge |
begin |
address <= address1_in ; |
pre_fetch_en <= pre_fetch_en1 ; |
end |
endcase |
end |
|
// Address claim output to PCI Target SM |
assign addr_claim_out = addr_claim ; |
|
reg [31:0] norm_address ; // stored normal address (decoded and translated) for access to WB |
reg norm_prf_en ; // stored pre-fetch enable |
reg [3:0] norm_bc ; // stored bus-command |
reg same_read_reg ; // stored SAME_READ information |
reg target_rd ; // delayed registered TRDY output equivalent signal |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
norm_address <= #`FF_DELAY 32'h0000_0000 ; |
norm_prf_en <= #`FF_DELAY 1'b0 ; |
norm_bc <= #`FF_DELAY 4'h0 ; |
same_read_reg <= #`FF_DELAY 1'b0 ; |
end |
else |
begin |
if (addr_phase_in) |
begin |
norm_address <= #`FF_DELAY address ; |
norm_prf_en <= #`FF_DELAY pre_fetch_en ; |
norm_bc <= #`FF_DELAY bc_in ; |
same_read_reg <= #`FF_DELAY same_read_out ; |
end |
end |
end |
|
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
reg [1:0] strd_address ; // stored INPUT address for accessing Configuration space registers |
`else |
reg [11:0] strd_address ; // stored INPUT address for accessing Configuration space registers |
`endif |
`else |
reg [11:0] strd_address ; // stored INPUT address for accessing Configuration space registers |
`endif |
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
strd_address <= #`FF_DELAY 0 ; |
end |
else |
begin |
if (addr_phase_in) |
begin |
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
strd_address <= #`FF_DELAY address_in[1:0] ; |
`else |
strd_address <= #`FF_DELAY address_in[11:0] ; |
`endif |
`else |
strd_address <= #`FF_DELAY address_in[11:0] ; |
`endif |
end |
end |
end |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
target_rd <= #`FF_DELAY 1'b0 ; |
end |
else |
begin |
if (same_read_reg && !bckp_trdy_in) |
target_rd <= #`FF_DELAY 1'b1 ;// Signal indicates when target ready is deaserted on PCI bus |
else if (same_read_reg && bckp_devsel_in && !bckp_stop_in) |
target_rd <= #`FF_DELAY 1'b1 ;// Signal indicates when target ready is deaserted on PCI bus |
else if ((!same_read_reg) || (last_reg_in && target_rd)) |
target_rd <= #`FF_DELAY 1'b0 ;// Signal indicates when target ready is deaserted on PCI bus |
end |
end |
// '1' indicates asserted TRDY signal when same read operation is performed |
wire target_rd_completed = target_rd ; |
|
reg same_read_request ; |
|
// When delayed read is completed on WB, addres and bc must be compered, if there is the same read request |
always@(address or strd_addr_in or bc_in or strd_bc_in) |
begin |
if ((address == strd_addr_in) & (bc_in == strd_bc_in)) |
same_read_request <= 1'b1 ; |
else |
same_read_request <= 1'b0 ; |
end |
|
assign same_read_out = (same_read_request) ; // && ~pcir_fifo_empty_in) ; |
|
// Signals for byte enable checking |
reg addr_burst_ok ; |
reg io_be_ok ; |
|
// Byte enable checking for IO, MEMORY and CONFIGURATION spaces - be_in is active low! |
always@(strd_address or be_in) |
begin |
case (strd_address[1:0]) |
2'b11 : |
begin |
addr_burst_ok <= 1'b0 ; |
io_be_ok <= (be_in[2] && be_in[1] && be_in[0]) ; // only be3 can be active |
end |
2'b10 : |
begin |
addr_burst_ok <= 1'b0 ; |
io_be_ok <= (~be_in[2] && be_in[1] && be_in[0]) || (be_in[3] && be_in[2] && be_in[1] && be_in[0]) ; |
end |
2'b01 : |
begin |
addr_burst_ok <= 1'b0 ; |
io_be_ok <= (~be_in[1] && be_in[0]) || (be_in[3] && be_in[2] && be_in[1] && be_in[0]) ; |
end |
default : // 2'b00 |
begin |
addr_burst_ok <= 1'b1 ; |
io_be_ok <= (~be_in[0]) || (be_in[3] && be_in[2] && be_in[1] && be_in[0]) ; |
end |
endcase |
end |
|
wire calc_target_abort = (norm_bc[3:1] == `BC_IO_RW) ? !io_be_ok : 1'b0 ; |
|
wire [3:0] pcir_fifo_control_input = pcir_fifo_empty_in ? 4'h0 : pcir_fifo_control_in ; |
|
// Medium registers for data and control busses from PCIR_FIFO |
reg [31:0] pcir_fifo_data_reg ; |
reg [3:0] pcir_fifo_ctrl_reg ; |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
pcir_fifo_data_reg <= #`FF_DELAY 32'h0000_0000 ; |
pcir_fifo_ctrl_reg <= #`FF_DELAY 4'h0 ; |
end |
else |
begin |
if (load_medium_reg_in) |
begin |
pcir_fifo_data_reg <= #`FF_DELAY pcir_fifo_data_in ; |
pcir_fifo_ctrl_reg <= #`FF_DELAY pcir_fifo_control_input ; |
end |
end |
end |
|
// when disconnect is signalled, the next data written to fifo will be the last |
// also when this happens, disconnect must stay asserted until last data is written to the fifo |
reg keep_desconnect_wo_data_set ; |
|
// selecting "fifo data" from medium registers or from PCIR_FIFO |
wire [31:0] pcir_fifo_data = (sel_fifo_mreg_in && !pcir_fifo_empty_in) ? pcir_fifo_data_in : pcir_fifo_data_reg ; |
wire [3:0] pcir_fifo_ctrl = (sel_fifo_mreg_in && !pcir_fifo_empty_in) ? pcir_fifo_control_input : pcir_fifo_ctrl_reg ; |
|
// signal assignments to PCI Target FSM |
assign read_completed_out = req_comp_pending_in ; // completion pending input for requesting side of the bridge |
assign read_processing_out = req_req_pending_in ; // request pending input for requesting side |
// when '1', the bus command is IO command - not supported commands are checked in pci_decoder modules |
wire io_memory_bus_command = !norm_bc[3] && !norm_bc[2] ; |
assign disconect_wo_data_out = ( |
((/*pcir_fifo_ctrl[`LAST_CTRL_BIT] ||*/ pcir_fifo_empty_in || ~burst_ok_out/*addr_burst_ok*/ || io_memory_bus_command) && |
~bc0_in && ~frame_reg_in) || |
((pciw_fifo_full_in || pciw_fifo_almost_full_in || keep_desconnect_wo_data_set || pciw_fifo_two_left_in || |
(pciw_fifo_three_left_in && pciw_fifo_wenable) || ~addr_burst_ok || io_memory_bus_command) && |
bc0_in && ~frame_reg_in) |
) ; |
assign disconect_w_data_out = ( |
( burst_ok_out && !io_memory_bus_command && ~bc0_in ) || |
( addr_burst_ok && !io_memory_bus_command && bc0_in ) |
) ; |
assign target_abort_out = ( ~addr_phase_in && calc_target_abort ) ; |
|
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
// signal assignments to PCI Target FSM |
assign norm_access_to_config_out = 1'b0 ; |
// control signal assignments to read request sinchronization module |
assign done_out = (target_rd_completed && last_reg_in) ; |
assign in_progress_out = (same_read_reg && ~bckp_trdy_in) ; |
// signal used for PCIR_FIFO flush (with comp_flush_in signal) |
wire pcir_fifo_flush = (target_rd_completed && last_reg_in && ~pcir_fifo_empty_in) ; |
`else |
// signal assignments to PCI Target FSM |
assign norm_access_to_config_out = (hit0_in && hit0_conf) ; |
// control signal assignments to read request sinchronization module |
assign done_out = (~sel_conf_fifo_in && target_rd_completed && last_reg_in) ; |
assign in_progress_out = (~sel_conf_fifo_in && same_read_reg && ~bckp_trdy_in) ; |
// signal used for PCIR_FIFO flush (with comp_flush_in signal) |
wire pcir_fifo_flush = (~sel_conf_fifo_in && target_rd_completed && last_reg_in && ~pcir_fifo_empty_in) ; |
`endif |
`else |
// signal assignments to PCI Target FSM |
assign norm_access_to_config_out = (hit0_in && hit0_conf) ; |
// control signal assignments to read request sinchronization module |
assign done_out = (~sel_conf_fifo_in && target_rd_completed && last_reg_in) ; |
assign in_progress_out = (~sel_conf_fifo_in && same_read_reg && ~bckp_trdy_in) ; |
// signal used for PCIR_FIFO flush (with comp_flush_in signal) |
wire pcir_fifo_flush = (~sel_conf_fifo_in && target_rd_completed && last_reg_in && ~pcir_fifo_empty_in) ; |
`endif |
|
// flush signal for PCIR_FIFO must be registered, since it asinchronously resets some status registers |
wire pcir_fifo_flush_reg ; |
pci_async_reset_flop async_reset_as_pcir_flush |
( |
.data_in (comp_flush_in || pcir_fifo_flush), |
.clk_in (clk_in), |
.async_reset_data_out (pcir_fifo_flush_reg), |
.reset_in (reset_in) |
) ; |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
keep_desconnect_wo_data_set <= #1 1'b0 ; |
else if (keep_desconnect_wo_data_set && pciw_fifo_wenable) |
keep_desconnect_wo_data_set <= #1 1'b0 ; |
else if (pciw_fifo_wenable && disconect_wo_data_out) |
keep_desconnect_wo_data_set <= #1 1'b1 ; |
end |
|
|
// signal assignments from fifo to PCI Target FSM |
assign wbw_fifo_empty_out = wbw_fifo_empty_in ; |
assign wbu_del_read_comp_pending_out = wbu_del_read_comp_pending_in ; |
assign pciw_fifo_full_out = (pciw_fifo_full_in || pciw_fifo_almost_full_in || pciw_fifo_two_left_in || pciw_fifo_three_left_in) ; |
assign pcir_fifo_data_err_out = pcir_fifo_ctrl[`DATA_ERROR_CTRL_BIT] && !sel_conf_fifo_in ; |
// signal assignments to PCIR FIFO fifo |
assign pcir_fifo_flush_out = pcir_fifo_flush_reg ; |
assign pcir_fifo_renable_out = fetch_pcir_fifo_in && !pcir_fifo_empty_in ; |
|
// signal assignments to PCIW FIFO |
reg pciw_fifo_wenable_out; |
assign pciw_fifo_wenable = load_to_pciw_fifo_in ; |
reg [3:0] pciw_fifo_control_out; |
reg [31:0] pciw_fifo_addr_data_out; |
reg [3:0] pciw_fifo_cbe_out; |
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
pciw_fifo_wenable_out <= #1 1'b0; |
pciw_fifo_control_out <= #1 4'h0; |
// data and address outputs assignments to PCIW_FIFO - correction of 2 LSBits |
pciw_fifo_addr_data_out <= #1 32'h0; |
pciw_fifo_cbe_out <= #1 4'h0; |
end |
else |
begin |
pciw_fifo_wenable_out <= #1 load_to_pciw_fifo_in ; |
pciw_fifo_control_out[`ADDR_CTRL_BIT] <= #1 ~rdy_in ; |
pciw_fifo_control_out[`BURST_BIT] <= #1 rdy_in ? ~frame_reg_in : 1'b0 ; |
// if '1' then next burst BE is not equat to current one => burst will be chopped into single transfers |
pciw_fifo_control_out[`DATA_ERROR_CTRL_BIT] <= #1 rdy_in && (next_be_in != be_in) && ~bckp_trdy_in; // valid comp. |
pciw_fifo_control_out[`LAST_CTRL_BIT] <= #1 rdy_in && (frame_reg_in || (bckp_trdy_in && ~bckp_stop_in)); |
// data and address outputs assignments to PCIW_FIFO - correction of 2 LSBits |
pciw_fifo_addr_data_out <= #1 rdy_in ? data_in : {norm_address[31:2], |
norm_address[1] && io_memory_bus_command, |
norm_address[0] && io_memory_bus_command} ; |
pciw_fifo_cbe_out <= #1 rdy_in ? be_in : norm_bc ; |
end |
end |
|
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
// data and address outputs assignments to PCI Target FSM |
assign data_out = pcir_fifo_data ; |
`else |
// data and address outputs assignments to PCI Target FSM |
assign data_out = sel_conf_fifo_in ? conf_data_in : pcir_fifo_data ; |
`endif |
`else |
// data and address outputs assignments to PCI Target FSM |
assign data_out = sel_conf_fifo_in ? conf_data_in : pcir_fifo_data ; |
`endif |
|
// data and address outputs assignments to read request sinchronization module |
assign req_out = req_in ; |
// this address is stored in delayed_sync module and is connected back as strd_addr_in |
assign addr_out = norm_address[31:0] ; // correction of 2 LSBits is done in wb_master module, original address must be saved |
assign be_out = be_in ; |
assign we_out = 1'b0 ; |
assign bc_out = norm_bc ; |
// burst is OK for reads when there is ((MEM_READ_LN or MEM_READ_MUL) and AD[1:0]==2'b00) OR |
// (MEM_READ and Prefetchable_IMAGE and AD[1:0]==2'b00) |
assign burst_ok_out = (norm_bc[3] && addr_burst_ok) || (norm_bc[2] && norm_prf_en && addr_burst_ok) ; |
// data and address outputs assignments to Configuration space |
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
assign conf_data_out = 32'h0 ; |
assign conf_addr_out = 12'h0 ; |
assign conf_be_out = 4'b0 ; |
assign conf_we_out = 1'h0 ; |
`else |
assign conf_data_out = data_in ; |
assign conf_addr_out = strd_address[11:0] ; |
assign conf_be_out = be_in ; |
assign conf_we_out = load_to_conf_in ; |
`endif |
`else |
assign conf_data_out = data_in ; |
assign conf_addr_out = strd_address[11:0] ; |
assign conf_be_out = be_in ; |
assign conf_we_out = load_to_conf_in ; |
`endif |
// NOT USED NOW, SONCE READ IS ASYNCHRONOUS |
//assign conf_re_out = fetch_conf_in ; |
assign conf_re_out = 1'b0 ; |
|
endmodule |
/verilog/pci_wb_slave.v
0,0 → 1,1201
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "wb_slave.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2003/08/03 18:05:06 mihad |
// Added limited WISHBONE B3 support for WISHBONE Slave Unit. |
// Doesn't support full speed bursts yet. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.4 2002/08/19 16:54:25 mihad |
// Got rid of undef directives |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`include "bus_commands.v" |
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_wb_slave |
( wb_clock_in, |
reset_in, |
wb_hit_in, |
wb_conf_hit_in, |
wb_map_in, |
wb_pref_en_in, |
wb_mrl_en_in, |
wb_addr_in, |
del_bc_in, |
wb_del_req_pending_in, |
wb_del_comp_pending_in, |
pci_drcomp_pending_in, |
del_bc_out, |
del_req_out, |
del_done_out, |
del_burst_out, |
del_write_out, |
del_write_in, |
del_error_in, |
del_in_progress_out, |
ccyc_addr_in, |
wb_del_addr_in, |
wb_del_be_in, |
wb_conf_offset_out, |
wb_conf_renable_out, |
wb_conf_wenable_out, |
wb_conf_be_out, |
wb_conf_data_in, |
wb_conf_data_out, |
wb_data_out, |
wb_cbe_out, |
wbw_fifo_wenable_out, |
wbw_fifo_control_out, |
wbw_fifo_almost_full_in, |
wbw_fifo_full_in, |
wbr_fifo_renable_out, |
wbr_fifo_be_in, |
wbr_fifo_data_in, |
wbr_fifo_control_in, |
wbr_fifo_flush_out, |
wbr_fifo_empty_in, |
pciw_fifo_empty_in, |
wbs_lock_in, |
cache_line_size_not_zero, |
sample_address_out, |
CYC_I, |
STB_I, |
WE_I, |
SEL_I, |
SDATA_I, |
SDATA_O, |
ACK_O, |
RTY_O, |
ERR_O, |
CAB_I |
); |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Various parameters needed for state machine and other stuff |
----------------------------------------------------------------------------------------------------------------------*/ |
parameter WBR_SEL = 1'b0 ; |
parameter CONF_SEL = 1'b1 ; |
|
`define FSM_BITS 3 |
parameter S_IDLE = `FSM_BITS'h0 ; |
parameter S_DEC1 = `FSM_BITS'h1 ; |
parameter S_DEC2 = `FSM_BITS'h2 ; |
parameter S_START = `FSM_BITS'h3 ; |
parameter S_W_ADDR_DATA = `FSM_BITS'h4 ; |
parameter S_READ = `FSM_BITS'h5 ; |
parameter S_CONF_WRITE = `FSM_BITS'h6 ; |
parameter S_CONF_READ = `FSM_BITS'h7 ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
System signals inputs |
wb_clock_in - WISHBONE bus clock input |
reset_in - system reset input controlled by bridge's reset logic |
----------------------------------------------------------------------------------------------------------------------*/ |
input wb_clock_in, reset_in ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Inputs from address decoding logic |
wb_hit_in - Decoder logic indicates if address is in a range of one of images |
wb_conf_hit_in - Decoder logic indicates that address is in configuration space range |
wb_map_in - Decoder logic provides information about image mapping - memory mapped image - wb_map_in = 0 |
IO space mapped image - wb_map_in = 1 |
wb_pref_en_in - Prefetch enable signal from currently selected image - used for PCI bus command usage |
wb_addr_in - Address already transalted from WB bus to PCI bus input |
wb_mrl_en_in - Memory read line enable input for each image |
----------------------------------------------------------------------------------------------------------------------*/ |
input [4:0] wb_hit_in ; // hit indicators |
input wb_conf_hit_in ; // configuration hit indicator |
input [4:0] wb_pref_en_in ; // prefetch enable from all images |
input [4:0] wb_mrl_en_in ; // Memory Read line command enable from images |
input [4:0] wb_map_in ; // address space mapping indicators - 1 memory space mapping, 0-IO space mapping |
input [31:0] wb_addr_in ; // Translated address input |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Delayed transaction control inputs and outputs: |
Used for locking particular accesses when delayed transactions are in progress: |
wb_del_addr_in - delayed transaction address input - when completion is ready it's used for transaction decoding |
wb_del_be_in - delayed transaction byte enable input - when completion is ready it's used for transaction decoding |
----------------------------------------------------------------------------------------------------------------------*/ |
input [31:0] wb_del_addr_in ; |
input [3:0] wb_del_be_in ; |
|
input [3:0] del_bc_in ; // delayed request bus command used |
input wb_del_req_pending_in ; // delayed request pending indicator |
input wb_del_comp_pending_in ; // delayed completion pending indicator |
input pci_drcomp_pending_in ; // PCI initiated delayed read completion pending |
|
output [3:0] del_bc_out ; // delayed transaction bus command output |
|
output del_req_out ; // output for issuing delayed transaction requests |
|
output del_done_out ; // output indicating current delayed completion finished on WISHBONE bus |
|
output del_burst_out ; // delayed burst transaction indicator |
|
output del_in_progress_out ; // delayed in progress indicator - since delayed transaction can be a burst transaction, progress indicator must be used for proper operation |
|
output del_write_out ; // write enable for delayed transaction - used for indicating that transaction is a write |
|
input del_write_in ; // indicates that current delayed completion is from a write request |
input del_error_in ; // indicate that delayed request terminated with an error - used for write requests |
|
input [31:0] ccyc_addr_in ; // configuration cycle address input - it's separate from other addresses, since it is stored separately and decoded for type 0 configuration access |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Configuration space access control and data signals |
wb_conf_offset_out - lower 12 bits of address input provided for register offset |
wb_conf_renable - read enable signal for configuration space accesses |
wb_conf_wenable - write enable signal for configuration space accesses |
wb_conf_be_out - byte enable signals for configuration space accesses |
wb_conf_data_in - data from configuration space |
wb_conf_data_in - data provided for configuration space |
----------------------------------------------------------------------------------------------------------------------*/ |
output [11:0] wb_conf_offset_out ; // register offset output |
output wb_conf_renable_out, // configuration read and write enable outputs |
wb_conf_wenable_out ; |
output [3:0] wb_conf_be_out ; // byte enable outputs for configuration space |
input [31:0] wb_conf_data_in ; // configuration data input from configuration space |
output [31:0] wb_conf_data_out ; // configuration data output for configuration space |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Data from WISHBONE bus output to interiror of the core: |
Data output is used for normal and configuration accesses. |
---------------------------------------------------------------------------------------------------------------------*/ |
output [31:0] wb_data_out ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Bus command - byte enable output - during address phase of image access this bus holds information about PCI |
bus command that should be used, during dataphases ( configuration or image access ) this bus contains inverted |
SEL_I signals |
---------------------------------------------------------------------------------------------------------------------*/ |
output [3:0] wb_cbe_out ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
WBW_FIFO control signals used for sinking data into WBW_FIFO and status monitoring |
---------------------------------------------------------------------------------------------------------------------*/ |
output wbw_fifo_wenable_out ; // write enable for WBW_FIFO output |
output [3:0] wbw_fifo_control_out ; // control bus output for WBW_FIFO |
input wbw_fifo_almost_full_in ; // almost full status indicator from WBW_FIFO |
input wbw_fifo_full_in ; // full status indicator from WBW_FIFO |
|
/*---------------------------------------------------------------------------------------------------------------------- |
WBR_FIFO control signals used for fetching data from WBR_FIFO and status monitoring |
---------------------------------------------------------------------------------------------------------------------*/ |
output wbr_fifo_renable_out ; // WBR_FIFO read enable output |
input [3:0] wbr_fifo_be_in ; // byte enable input from WBR_FIFO |
input [31:0] wbr_fifo_data_in ; // data input from WBR_FIFO |
input [3:0] wbr_fifo_control_in ; // control bus input from WBR_FIFO |
output wbr_fifo_flush_out ; // flush signal for WBR_FIFO |
input wbr_fifo_empty_in ; // empty status indicator from WBR_FIFO |
|
// used for transaction ordering requirements - WISHBONE read cannot complete until writes from PCI are completed |
input pciw_fifo_empty_in ; // empty status indicator from PCIW_FIFO |
|
/*---------------------------------------------------------------------------------------------------------------------- |
wbs_lock_in: internal signal that locks out all accesses, except delayed completions or configuration accesses. |
( when master operation is disabled via master enable bit in configuration spacei ) |
---------------------------------------------------------------------------------------------------------------------*/ |
input wbs_lock_in ; |
|
// cache line size register must hold appropriate value to enable read bursts and special commands on PCI bus! |
input cache_line_size_not_zero ; |
|
// state machine signals to wb_addr_mux when to sample wb address input |
output sample_address_out ; |
reg sample_address_out ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
WISHBONE bus interface signals - can be connected directly to WISHBONE bus |
---------------------------------------------------------------------------------------------------------------------*/ |
input CYC_I ; // cycle indicator |
input STB_I ; // strobe input - input data is valid when strobe and cycle indicator are high |
input WE_I ; // write enable input - 1 - write operation, 0 - read operation |
input [3:0] SEL_I ; // Byte select inputs |
input [31:0] SDATA_I ; // WISHBONE slave interface input data bus |
output [31:0] SDATA_O ; // WISHBONE slave interface output data bus |
output ACK_O ; // Acknowledge output - qualifies valid data on data output bus or received data on data input bus |
output RTY_O ; // retry output - signals to WISHBONE master that cycle should be terminated and retried later |
output ERR_O ; // Signals to WISHBONE master that access resulted in an error |
input CAB_I ; // consecutive address burst input - indicates that master will do a serial address transfer in current cycle |
|
`ifdef REGISTER_WBS_OUTPUTS |
reg [31:0] SDATA_O ; |
reg ACK_O ; |
reg RTY_O ; |
reg ERR_O ; |
|
reg [3:0] del_bc_out ; // delayed transaction bus command output |
reg del_req_out ; // output for issuing delayed transaction requests |
reg del_done_out ; // output indicating current delayed completion finished on WISHBONE bus |
reg del_burst_out ; // delayed burst transaction indicator |
reg del_in_progress_out ; // delayed in progress indicator - since delayed transaction can be a burst transaction, progress indicator must be used for proper operation |
reg del_write_out ; // write enable for delayed transaction - used for indicating that transaction is a write |
|
`ifdef HOST |
reg wb_conf_wenable_out ; |
reg [31:0] wb_conf_data_out ; // configuration data output for configuration space |
`endif |
|
reg [3:0] wb_conf_be_out ; // byte enable outputs for configuration space |
reg [31:0] wb_data_out ; |
|
reg [3:0] wb_cbe_out ; |
|
reg wbw_fifo_wenable_out ; // write enable for WBW_FIFO output |
reg [3:0] wbw_fifo_control_out ; // control bus output for WBW_FIFO |
|
reg wbr_fifo_renable_out ; // WBR_FIFO read enable output |
`endif |
|
reg [(`FSM_BITS - 1):0] c_state ; //current state register |
|
reg [(`FSM_BITS - 1):0] n_state ; //next state input to current state register |
|
// state machine register control |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) |
c_state <= #`FF_DELAY S_IDLE ; |
else |
c_state <= #`FF_DELAY n_state ; |
end |
|
|
// variable for bus command multiplexer logic output for delayed requests |
reg [3:0] del_bc ; |
|
//register for intermediate data and select storage |
reg [35:0] d_incoming ; |
|
// enable for incoming data register |
reg d_incoming_ena ; |
|
// incoming data register control logic |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) |
d_incoming <= #`FF_DELAY {35{1'b0}} ; |
else if (d_incoming_ena) |
d_incoming <= #`FF_DELAY {SEL_I, SDATA_I} ; |
end |
|
/*=================================================================================================================================================================================== |
Write allow for image accesses. Writes through images are allowed when all of following are true: |
- WBW_FIFO musn't be almost full nor full for image writes to be allowed - Every transaction takes at least two locations in the FIFO |
- delayed read from from WISHBONE to PCI request musn't be present |
- delayed read from PCI to WISHBONE completion musn't be present |
- lock input musn't be set - it can be set because of error reporting or because PCI master state machine is disabled |
===================================================================================================================================================================================*/ |
wire wimg_wallow = ~|{ wbw_fifo_almost_full_in , wbw_fifo_full_in, wb_del_req_pending_in, pci_drcomp_pending_in, wbs_lock_in } ; |
reg img_wallow ; |
/*=================================================================================================================================================================================== |
WISHBONE slave can request an image read accesses when all of following are true: |
- delayed completion is not present |
- delayed request is not present |
- operation is not locked because of error reporting mechanism or because PCI master is disabled |
===================================================================================================================================================================================*/ |
wire wdo_del_request = ~|{ wb_del_req_pending_in, wb_del_comp_pending_in, wbs_lock_in } ; |
reg do_del_request ; |
/*=================================================================================================================================================================================== |
WISHBONE slave can complete an image read accesses when all of following are true: |
- delayed read completion is present |
- delayed read completion is the same as current read access ( dread_completion_hit is 1 ) |
- PCI Write FIFO is empty - no posted write is waiting to be finished in PCIW_FIFO |
- WBR_FIFO empty status is not active |
===================================================================================================================================================================================*/ |
wire wdel_addr_hit = ( wb_del_addr_in == wb_addr_in ) && ( SEL_I == wb_del_be_in ) ; |
reg del_addr_hit ; |
wire wdel_completion_allow = wb_del_comp_pending_in && ((~del_write_in && ~WE_I && pciw_fifo_empty_in && ~wbr_fifo_empty_in) || (del_write_in && WE_I)) ; |
reg del_completion_allow ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
img_hit - state of wb_hit_in bus when when state machine signals decode is over |
---------------------------------------------------------------------------------------------------------------------*/ |
reg [4:0] img_hit ; |
wire wb_hit = |( img_hit ) ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Control logic for image control signals |
pref_en - prefetch enable of currently selected image |
mrl_en - Memory read line enable of currently selected image |
map - Address space mapping for currently selected image |
---------------------------------------------------------------------------------------------------------------------*/ |
reg pref_en, mrl_en, map ; |
wire wpref_en = |(wb_pref_en_in & wb_hit_in) ; |
wire wmrl_en = |(wb_mrl_en_in & wb_hit_in) ; |
wire wmap = |(wb_map_in & wb_hit_in) ; |
|
// state machine controls when results from decoders, comparison etc. are sampled into registers to decode an access |
reg decode_en ; |
|
reg wb_conf_hit ; |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
begin |
img_wallow <= #`FF_DELAY 1'b0 ; |
wb_conf_hit <= #`FF_DELAY 1'b0 ; |
do_del_request <= #`FF_DELAY 1'b0 ; |
del_addr_hit <= #`FF_DELAY 1'b0 ; |
del_completion_allow <= #`FF_DELAY 1'b0 ; |
img_hit <= #`FF_DELAY 5'h00 ; |
pref_en <= #`FF_DELAY 1'b0 ; |
mrl_en <= #`FF_DELAY 1'b0 ; |
map <= #`FF_DELAY 1'b0 ; |
end |
else |
if (decode_en) |
begin |
img_wallow <= #`FF_DELAY wimg_wallow ; |
wb_conf_hit <= #`FF_DELAY wb_conf_hit_in ; |
do_del_request <= #`FF_DELAY wdo_del_request ; |
del_addr_hit <= #`FF_DELAY wdel_addr_hit ; |
del_completion_allow <= #`FF_DELAY wdel_completion_allow ; |
img_hit <= #`FF_DELAY wb_hit_in ; |
pref_en <= #`FF_DELAY wpref_en && cache_line_size_not_zero ; |
mrl_en <= #`FF_DELAY wmrl_en && cache_line_size_not_zero ; |
map <= #`FF_DELAY wmap ; |
end |
end |
|
wire del_burst = CAB_I && (pref_en || mrl_en) && ~WE_I && cache_line_size_not_zero ; // delayed burst indicator - only when WB master attempts CAB transfer and cache line size register is set appropriately and |
// either prefetch enable or memory read line enable of corresponding image are set - |
// applies for reads only - delayed write cannot be a burst |
wire do_dread_completion = del_completion_allow && del_addr_hit ; |
|
// address allignement indicator |
wire alligned_address = ~|(wb_addr_in[1:0]) ; |
|
`ifdef GUEST |
|
// wires indicating allowance for configuration cycle generation requests |
wire do_ccyc_req = 1'b0 ; |
wire do_ccyc_comp = 1'b0 ; |
|
// wires indicating allowance for interrupt acknowledge cycle generation requests |
wire do_iack_req = 1'b0 ; |
wire do_iack_comp = 1'b0 ; |
|
// variables for configuration access control signals |
reg conf_wenable ; |
assign wb_conf_wenable_out = 1'b0 ; |
|
// configuration cycle data register hit |
wire ccyc_hit = 1'b0 ; |
wire iack_hit = 1'b0 ; |
|
wire wccyc_hit = 1'b0 ; |
wire wiack_hit = 1'b0 ; |
|
`else |
`ifdef HOST |
// only host implementation has access for generating interrupt acknowledge and configuration cycles |
// configuration cycle data register hit |
reg current_delayed_is_ccyc ; |
reg current_delayed_is_iack ; |
|
wire wccyc_hit = (wb_addr_in[8:2] == {1'b1, `CNF_DATA_ADDR}) |
`ifdef PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
`else |
&& alligned_address |
`endif |
; |
wire wiack_hit = (wb_addr_in[8:2] == {1'b1, `INT_ACK_ADDR}) |
`ifdef PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
`else |
&& alligned_address |
`endif |
; |
reg iack_hit ; |
reg ccyc_hit ; |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
begin |
ccyc_hit <= #`FF_DELAY 1'b0 ; |
iack_hit <= #`FF_DELAY 1'b0 ; |
end |
else |
if (decode_en) |
begin |
ccyc_hit <= #`FF_DELAY wccyc_hit ; |
iack_hit <= #`FF_DELAY wiack_hit ; |
end |
end |
|
// wires indicating allowance for configuration cycle generation requests |
wire do_ccyc_req = do_del_request && ccyc_hit; |
wire do_ccyc_comp = del_completion_allow && ccyc_hit && current_delayed_is_ccyc ; // && del_bc_hit |
|
// wires indicating allowance for interrupt acknowledge cycle generation requests |
wire do_iack_req = do_del_request && iack_hit ; |
wire do_iack_comp = del_completion_allow && iack_hit && current_delayed_is_iack ; // && del_bc_hit |
|
// variables for configuration access control signals |
reg conf_wenable ; |
|
// following flip-flops remember whether current delayed transaction is interrupt acknowledge or configuration cycle transaction |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if ( reset_in ) |
begin |
current_delayed_is_ccyc <= #`FF_DELAY 1'b0 ; |
current_delayed_is_iack <= #`FF_DELAY 1'b0 ; |
end |
else |
if ( del_done_out ) |
begin |
current_delayed_is_ccyc <= #`FF_DELAY 1'b0 ; |
current_delayed_is_iack <= #`FF_DELAY 1'b0 ; |
end |
else |
if ( del_req_out && wb_conf_hit ) |
begin |
current_delayed_is_ccyc <= #`FF_DELAY do_ccyc_req ; |
current_delayed_is_iack <= #`FF_DELAY do_iack_req ; |
end |
end |
|
`endif |
`endif |
|
// configuration read enable - supplied for host and guest bridges |
reg conf_renable ; |
assign wb_conf_renable_out = conf_renable ; |
|
// burst access indicator |
wire burst_transfer = CYC_I && CAB_I ; |
|
// SEL_I error indicator for IO accesses - select lines must be alligned with address |
reg sel_error ; |
always@(wb_addr_in or SEL_I) |
begin |
case (wb_addr_in[1:0]) |
2'b00: sel_error = ~SEL_I[0] ; // select 0 must be 1, all others are don't cares. |
2'b01: sel_error = ~SEL_I[1] || SEL_I[0] ; // byte 0 can't be selected, byte 1 must be selected |
2'b10: sel_error = ~SEL_I[2] || SEL_I[1] || SEL_I[0] ; // bytes 0 and 1 can't be selected, byte 2 must be selected |
2'b11: sel_error = ~SEL_I[3] || SEL_I[2] || SEL_I[1] || SEL_I[0] ; // bytes 0, 1 and 2 can't be selected, byte 3 must be selected |
endcase |
end |
|
// WBW_FIFO control output |
reg [3:0] wbw_fifo_control ; |
|
// WBW_FIFO wenable output assignment |
reg wbw_fifo_wenable ; |
|
// WBR_FIFO control outputs |
reg wbr_fifo_flush, wbr_fifo_renable ; // flush and read enable outputs |
|
// flush signal for WBR_FIFO must be registered, since it asinchronously resets some status registers |
wire wbr_fifo_flush_reg ; |
pci_async_reset_flop async_reset_as_wbr_flush |
( |
.data_in (wbr_fifo_flush), |
.clk_in (wb_clock_in), |
.async_reset_data_out (wbr_fifo_flush_reg), |
.reset_in (reset_in) |
) ; |
assign wbr_fifo_flush_out = wbr_fifo_flush_reg ; |
|
// delayed transaction request control signals |
reg del_req, del_done ; |
|
// WISHBONE handshaking control outputs |
reg ack, rty, err ; |
|
`ifdef REGISTER_WBS_OUTPUTS |
// wire for write attempt - 1 when external WB master is attempting a write |
// wire for read attempt - 1 when external master is attempting a read |
wire wattempt = ( CYC_I && STB_I && WE_I ) && (!ACK_O && !ERR_O && !RTY_O) ; |
wire rattempt = ( CYC_I && STB_I && ~WE_I ) && (!ACK_O && !ERR_O && !RTY_O) ; |
|
`else |
// wire for write attempt - 1 when external WB master is attempting a write |
// wire for read attempt - 1 when external master is attempting a read |
wire wattempt = ( CYC_I && STB_I && WE_I ) ; // write is qualified when cycle, strobe and write enable inputs are all high |
wire rattempt = ( CYC_I && STB_I && ~WE_I ) ; // read is qualified when cycle and strobe are high and write enable is low |
|
`endif |
/*---------------------------------------------------------------------------------------------------------------------- |
Delayed transaction bus command generation |
Bus command for delayed reads depends on image's address space mapping and control bits and |
whether or not these are interrupt acknowledge requests or configuration cycle requests |
---------------------------------------------------------------------------------------------------------------------*/ |
|
always@(map or mrl_en or ccyc_hit or WE_I or wb_conf_hit or CAB_I or pref_en) |
begin |
`ifdef HOST |
// only host implementation supports configuration and interrupt acknowledge commands |
if (wb_conf_hit) |
begin |
case( {ccyc_hit, WE_I} ) |
2'b11: del_bc = `BC_CONF_WRITE ; |
2'b10: del_bc = `BC_CONF_READ ; |
2'b01: del_bc = `BC_RESERVED0 ; // invalid combination - interrupt acknowledge cycle must be a read |
2'b00: del_bc = `BC_IACK ; |
endcase |
end |
else |
`endif |
begin |
if ( map ) |
begin |
del_bc = `BC_IO_READ ; |
end |
else |
begin |
case ({(CAB_I && mrl_en), pref_en}) |
2'b00: del_bc = `BC_MEM_READ ; // if this is not burst transfer or memory read line command is disabled - use memory read |
2'b01: del_bc = `BC_MEM_READ ; // same as previous case |
2'b10: del_bc = `BC_MEM_READ_LN ; // burst transfer, memory read line command enabled, prefetch disabled - use memory read line command |
2'b11: del_bc = `BC_MEM_READ_MUL ; // same as previous case, except prefetch is enabled - use memory read multiple command |
endcase |
end |
end |
end |
|
reg del_in_progress ; // state machine indicates whether current read completion is in progress on WISHBONE bus |
|
wire image_access_error = (map && (burst_transfer || sel_error)) || // IO write is a burst or has wrong select lines active= Error |
(~map && ~alligned_address) ; // Mem write to nonaligned address = error; |
|
`ifdef HOST |
reg [1:0] wbw_data_out_sel ; |
parameter SEL_ADDR_IN = 2'b10 ; |
parameter SEL_CCYC_ADDR = 2'b11 ; |
parameter SEL_DATA_IN = 2'b00 ; |
`else |
`ifdef GUEST |
reg wbw_data_out_sel ; |
parameter SEL_ADDR_IN = 1'b1 ; |
parameter SEL_DATA_IN = 1'b0 ; |
`endif |
`endif |
|
`ifdef WB_DECODE_FAST |
`ifdef REGISTER_WBS_OUTPUTS |
`define PCI_WB_SLAVE_S_DEC1 |
`endif |
`endif |
|
`ifdef WB_DECODE_MEDIUM |
`define PCI_WB_SLAVE_S_DEC1 |
`endif |
|
`ifdef WB_DECODE_SLOW |
`define PCI_WB_SLAVE_S_DEC1 |
`define PCI_WB_SLAVE_S_DEC2 |
`endif |
// state machine logic |
always@( |
c_state or |
wattempt or |
img_wallow or |
burst_transfer or |
wb_hit or |
map or |
alligned_address or |
rattempt or |
do_dread_completion or |
wbr_fifo_control_in or |
wb_conf_hit or |
do_ccyc_req or |
do_ccyc_comp or |
ccyc_hit or |
del_error_in or |
do_iack_req or |
do_iack_comp or |
iack_hit or |
image_access_error or |
wbw_fifo_almost_full_in or |
wbw_fifo_full_in or |
do_del_request or |
wbr_fifo_empty_in |
) |
begin |
// default signal values |
// response signals inactive |
ack = 1'b0 ; |
rty = 1'b0 ; |
err = 1'b0 ; |
|
//write signals inactive |
wbw_fifo_control[`ADDR_CTRL_BIT] = 1'b1 ; |
wbw_fifo_control[`DATA_ERROR_CTRL_BIT] = 1'b0 ; |
wbw_fifo_control[`LAST_CTRL_BIT] = 1'b0 ; |
wbw_fifo_control[`UNUSED_CTRL_BIT] = 1'b0 ; |
|
wbw_fifo_wenable = 1'b0 ; |
d_incoming_ena = 1'b0 ; |
|
// read signals inactive |
wbr_fifo_flush = 1'b0 ; |
wbr_fifo_renable = 1'b0 ; |
del_req = 1'b0 ; |
del_done = 1'b0 ; |
|
// configuration space control signals inactive |
conf_wenable = 1'b0 ; |
conf_renable = 1'b0 ; |
|
// read is not in progress |
del_in_progress = 1'b0 ; |
|
decode_en = 1'b0 ; |
|
wbw_data_out_sel = SEL_ADDR_IN ; |
|
sample_address_out = 1'b0 ; |
|
case (c_state) |
S_IDLE: begin |
if ( wattempt || rattempt ) |
begin |
|
`ifdef PCI_WB_SLAVE_S_DEC1 |
n_state = S_DEC1 ; |
`else |
decode_en = 1'b1 ; |
n_state = S_START ; |
`endif |
|
sample_address_out = 1'b1 ; |
end |
else |
n_state = S_IDLE ; |
end |
`ifdef PCI_WB_SLAVE_S_DEC1 |
S_DEC1: begin |
if ( wattempt || rattempt ) |
begin |
|
`ifdef PCI_WB_SLAVE_S_DEC2 |
n_state = S_DEC2 ; |
`else |
decode_en = 1'b1 ; |
n_state = S_START ; |
`endif |
|
end |
else |
n_state = S_IDLE ; |
end |
`endif |
`ifdef PCI_WB_SLAVE_S_DEC2 |
S_DEC2: begin |
|
if ( wattempt || rattempt ) |
begin |
decode_en = 1'b1 ; |
n_state = S_START ; |
end |
else |
n_state = S_IDLE ; |
end |
`endif |
S_START:begin |
if (wb_conf_hit) // configuration space hit |
begin |
`ifdef HOST |
wbw_data_out_sel = SEL_CCYC_ADDR ; |
`endif |
|
if ( wattempt ) |
n_state = S_CONF_WRITE ; // go to conf. write state |
else |
if ( rattempt ) |
begin |
n_state = S_CONF_READ ; // go to conf. read state |
end |
else |
n_state = S_IDLE ; // master terminated - go back to idle state |
|
end // wb_conf_hit |
else |
if( wb_hit && (wattempt || rattempt) ) |
begin |
wbw_data_out_sel = SEL_DATA_IN ; |
|
// check error conditions for image writes or reads |
if ( image_access_error ) |
begin |
n_state = S_IDLE ; // go back to idle state because of an error condition |
err = 1'b1 ; |
end // error conditions |
else |
// check for retry conditions for image writes or reads |
if ( (wattempt && ~img_wallow) || |
(rattempt && ~do_dread_completion) // write to image not allowed, no read ready yet - retry |
) |
begin |
n_state = S_IDLE ; // go back to IDLE |
|
rty = 1'b1 ; |
|
del_req = do_del_request && rattempt ; |
|
end //retry |
else // everything OK - proceed |
if ( wattempt ) |
begin |
n_state = S_W_ADDR_DATA ; // goto write transfer state |
|
// respond with acknowledge |
ack = 1'b1 ; |
|
wbw_fifo_wenable = 1'b1 ; |
|
// data is latched to data incoming intermidiate stage - it will be put in FIFO later |
d_incoming_ena = 1'b1 ; |
end |
else |
begin |
err = wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] ; |
ack = ~wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] ; |
wbr_fifo_renable = 1'b1 ; |
del_in_progress = 1'b1 ; |
|
if ( wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] || wbr_fifo_control_in[`LAST_CTRL_BIT] ) |
begin |
|
n_state = S_IDLE ; // go back to idle state |
// respond that read is finished |
del_done = 1'b1 ; |
|
end // end read |
else |
n_state = S_READ ; // go to read state |
end |
end |
else |
n_state = S_IDLE ; |
|
end |
|
S_W_ADDR_DATA: begin |
wbw_data_out_sel = SEL_DATA_IN ; |
err = burst_transfer && wattempt && ~alligned_address ; |
rty = burst_transfer && wattempt && (wbw_fifo_almost_full_in || wbw_fifo_full_in) ; |
|
if ( ~burst_transfer || wattempt && ( ~alligned_address || wbw_fifo_almost_full_in || wbw_fifo_full_in ) ) |
begin |
n_state = S_IDLE ; |
|
// write last data to FIFO and don't latch new data |
wbw_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ; |
wbw_fifo_control[`LAST_CTRL_BIT] = 1'b1 ; |
wbw_fifo_wenable = 1'b1 ; |
end |
else |
begin |
n_state = S_W_ADDR_DATA ; |
wbw_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ; |
wbw_fifo_control[`LAST_CTRL_BIT] = 1'b0 ; |
ack = wattempt ; |
wbw_fifo_wenable = wattempt ; |
d_incoming_ena = wattempt ; |
end |
end // S_W_ADDR_DATA |
|
S_READ:begin |
// this state is for reads only - in this state read is in progress all the time |
del_in_progress = 1'b1 ; |
|
ack = burst_transfer && rattempt && ~wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] && alligned_address && ~wbr_fifo_empty_in ; |
err = burst_transfer && rattempt && ((wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] || ~alligned_address) && ~wbr_fifo_empty_in) ; |
//rty = burst_transfer && rattempt && wbr_fifo_empty_in && alligned_address ; |
|
// if acknowledge is beeing signalled then enable read from wbr fifo |
wbr_fifo_renable = burst_transfer && rattempt && alligned_address && ~wbr_fifo_empty_in ; |
|
if ( ~burst_transfer || rattempt && (~alligned_address || wbr_fifo_empty_in || wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] || wbr_fifo_control_in[`LAST_CTRL_BIT]) ) |
begin |
n_state = S_IDLE ; |
del_done = 1'b1 ; |
wbr_fifo_flush = ~wbr_fifo_empty_in ; |
end |
else |
begin |
n_state = S_READ ; |
end |
end // S_READ |
|
S_CONF_WRITE: begin |
`ifdef HOST |
wbw_data_out_sel = SEL_CCYC_ADDR ; |
del_req = do_ccyc_req && ~burst_transfer |
`ifdef PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
`else |
&& alligned_address |
`endif |
; |
del_done = do_ccyc_comp && ~burst_transfer |
`ifdef PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
`else |
&& alligned_address |
`endif |
; |
del_in_progress = do_ccyc_comp && ~burst_transfer |
`ifdef PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
`else |
&& alligned_address |
`endif |
; |
`endif |
|
n_state = S_IDLE ; // next state after configuration access is always idle |
|
if ( burst_transfer |
`ifdef PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
`else |
| ~alligned_address |
`endif |
) |
begin |
err = 1'b1 ; |
end |
else |
begin |
`ifdef HOST |
if ( do_ccyc_req || (ccyc_hit && ~do_ccyc_comp)) |
begin |
rty = 1'b1 ; |
end |
else |
if ( do_ccyc_comp ) |
begin |
err = del_error_in ; |
ack = ~del_error_in ; |
end |
else |
begin |
ack = ~ccyc_hit ; |
conf_wenable = ~ccyc_hit ; |
end |
`else |
ack = 1'b1 ; |
conf_wenable = 1'b1 ; |
`endif |
end |
end // S_CONF_WRITE |
|
S_CONF_READ: begin |
`ifdef HOST |
wbw_data_out_sel = SEL_CCYC_ADDR ; |
del_req = ~burst_transfer |
`ifdef PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
`else |
&& alligned_address |
`endif |
&& ( do_ccyc_req || do_iack_req ) ; |
del_done = ~burst_transfer |
`ifdef PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
`else |
&& alligned_address |
`endif |
&& ( do_ccyc_comp || do_iack_comp ) ; |
del_in_progress = ~burst_transfer |
`ifdef PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
`else |
&& alligned_address |
`endif |
&& ( do_ccyc_comp || do_iack_comp ) ; |
wbr_fifo_renable = ~burst_transfer |
`ifdef PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
`else |
&& alligned_address |
`endif |
&& ( do_ccyc_comp || do_iack_comp ) ; |
`endif |
|
n_state = S_IDLE ; // next state after configuration access is always idle |
|
if ( burst_transfer |
`ifdef PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
`else |
| ~alligned_address |
`endif |
) |
begin |
err = 1'b1 ; |
end |
else |
begin |
`ifdef HOST |
if ( do_ccyc_req || ( ccyc_hit && ~do_ccyc_comp )) |
begin |
rty = 1'b1 ; |
end |
else |
if ( do_iack_req || ( iack_hit && ~do_iack_comp )) |
begin |
rty = 1'b1 ; |
end |
else |
if ( do_iack_comp || do_ccyc_comp ) |
begin |
err = del_error_in ; |
ack = ~del_error_in ; |
end |
else |
begin |
ack = ~( ccyc_hit || iack_hit ) ; |
conf_renable = ~( ccyc_hit || iack_hit ) ; |
end |
`else |
ack = 1'b1 ; |
conf_renable = 1'b1 ; |
`endif |
end |
end //S_CONF_READ |
default:begin |
n_state = S_IDLE ; // return to idle state |
end //default |
endcase |
end |
|
// configuration space offset output assignment |
assign wb_conf_offset_out = {wb_addr_in[11:2], 2'b00} ; // upper 10 bits of address input and two zeros |
|
// data output assignment - for image writes, first data is address, subsequent data comes from intermediate register |
reg [31:0] wb_data ; |
`ifdef HOST |
reg [1:0] wbw_data_out_sel_reg ; |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if ( reset_in ) |
wbw_data_out_sel_reg <= #`FF_DELAY SEL_ADDR_IN ; |
else |
wbw_data_out_sel_reg <= #`FF_DELAY wbw_data_out_sel ; |
end |
|
always@(wbw_data_out_sel_reg or wb_addr_in or ccyc_addr_in or d_incoming) |
begin |
case ( wbw_data_out_sel_reg ) |
SEL_CCYC_ADDR: wb_data = ccyc_addr_in ; |
SEL_DATA_IN: wb_data = d_incoming ; |
default: wb_data = wb_addr_in ; |
endcase |
end |
`else |
`ifdef GUEST |
reg wbw_data_out_sel_reg ; |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if ( reset_in ) |
wbw_data_out_sel_reg <= #`FF_DELAY SEL_ADDR_IN ; |
else |
wbw_data_out_sel_reg <= #`FF_DELAY wbw_data_out_sel ; |
end |
|
always@(wbw_data_out_sel_reg or wb_addr_in or d_incoming) |
begin |
if ( wbw_data_out_sel_reg ) |
wb_data = wb_addr_in ; |
else |
wb_data = d_incoming ; |
end |
`endif |
`endif |
|
// command / byte enable assignment - with address, bus command is provided, with data - byte enables are provided |
reg [3:0] wb_cbe ; |
|
always@(wbw_data_out_sel_reg or d_incoming or map) |
begin |
if (wbw_data_out_sel_reg && map) |
wb_cbe = `BC_IO_WRITE ; |
else |
if (wbw_data_out_sel_reg) |
wb_cbe = `BC_MEM_WRITE ; |
else |
wb_cbe = ~(d_incoming[35:32]) ; |
end |
|
// for configuration writes, data output is always data from WISHBONE - in guest implementation data is all 0. |
`ifdef GUEST |
assign wb_conf_data_out = 32'h00000000 ; |
`endif |
|
`ifdef GUEST |
`ifdef NO_CNF_IMAGE |
`else |
`define PCI_WB_SLAVE_DO_OUT_MUX |
`endif |
`else |
`ifdef HOST |
`define PCI_WB_SLAVE_DO_OUT_MUX ; |
`endif |
`endif |
|
`ifdef PCI_WB_SLAVE_DO_OUT_MUX |
reg [31:0] sdata_source ; |
|
// WISHBONE data output select lines for output multiplexor |
wire sdata_o_sel_new = ( wb_conf_hit_in && ~wiack_hit && ~wccyc_hit ) ? CONF_SEL : WBR_SEL ; |
reg sdata_o_sel ; |
|
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if ( reset_in ) |
sdata_o_sel <= #`FF_DELAY WBR_SEL ; |
else |
if ( decode_en ) |
sdata_o_sel <= #`FF_DELAY sdata_o_sel_new ; |
end |
|
always@(sdata_o_sel or wbr_fifo_data_in or wb_conf_data_in) |
begin |
case (sdata_o_sel) |
WBR_SEL :sdata_source = wbr_fifo_data_in ; |
CONF_SEL:sdata_source = wb_conf_data_in ; |
endcase |
end |
`else |
wire [31:0] sdata_source = wbr_fifo_data_in ; |
`endif |
|
`ifdef REGISTER_WBS_OUTPUTS |
|
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if ( reset_in ) |
begin |
ACK_O <= #`FF_DELAY 1'b0 ; |
RTY_O <= #`FF_DELAY 1'b0 ; |
ERR_O <= #`FF_DELAY 1'b0 ; |
SDATA_O <= #`FF_DELAY 0 ; |
del_write_out <= #`FF_DELAY 1'b0 ; |
|
`ifdef HOST |
wb_conf_wenable_out <= #`FF_DELAY 1'b0 ; |
wb_conf_data_out <= #`FF_DELAY 0 ; |
`endif |
|
del_bc_out <= #`FF_DELAY `BC_RESERVED0 ; |
del_req_out <= #`FF_DELAY 1'b0 ; |
del_done_out <= #`FF_DELAY 1'b0 ; |
del_burst_out <= #`FF_DELAY 1'b0 ; |
del_in_progress_out <= #`FF_DELAY 1'b0 ; |
wb_conf_be_out <= #`FF_DELAY 0 ; |
wb_data_out <= #`FF_DELAY 0 ; |
wb_cbe_out <= #`FF_DELAY 0 ; |
wbw_fifo_wenable_out <= #`FF_DELAY 0 ; |
wbw_fifo_control_out <= #`FF_DELAY 0 ; |
wbr_fifo_renable_out <= #`FF_DELAY 0 ; |
end |
else |
begin |
ACK_O <= #`FF_DELAY ack && !ACK_O ; |
RTY_O <= #`FF_DELAY rty && !RTY_O ; |
ERR_O <= #`FF_DELAY err && !ERR_O ; |
SDATA_O <= #`FF_DELAY sdata_source ; |
del_write_out <= #`FF_DELAY WE_I ; |
|
`ifdef HOST |
wb_conf_wenable_out <= #`FF_DELAY conf_wenable ; |
wb_conf_data_out <= #`FF_DELAY SDATA_I ; |
`endif |
|
del_bc_out <= #`FF_DELAY del_bc ; |
del_req_out <= #`FF_DELAY del_req ; |
del_done_out <= #`FF_DELAY del_done ; |
del_burst_out <= #`FF_DELAY del_burst ; |
del_in_progress_out <= #`FF_DELAY del_in_progress ; |
wb_conf_be_out <= #`FF_DELAY SEL_I ; |
wb_data_out <= #`FF_DELAY wb_data ; |
wb_cbe_out <= #`FF_DELAY wb_cbe ; |
wbw_fifo_wenable_out <= #`FF_DELAY wbw_fifo_wenable ; |
wbw_fifo_control_out <= #`FF_DELAY wbw_fifo_control ; |
wbr_fifo_renable_out <= #`FF_DELAY wbr_fifo_renable ; |
end |
end |
|
`else |
|
assign SDATA_O = sdata_source ; |
|
assign ACK_O = ack ; |
assign RTY_O = rty ; |
assign ERR_O = err ; |
|
// write operation indicator for delayed transaction requests |
assign del_write_out = WE_I ; |
assign del_bc_out = del_bc ; |
assign del_req_out = del_req ; // read request |
assign del_done_out = del_done ; // read done |
assign del_burst_out = del_burst ; |
assign del_in_progress_out = del_in_progress ; |
`ifdef HOST |
assign wb_conf_data_out = SDATA_I ; |
assign wb_conf_wenable_out = conf_wenable ; |
`endif |
// Configuration space byte enables output |
assign wb_conf_be_out = SEL_I ; // just route select lines from WISHBONE to conf space |
assign wb_data_out = wb_data ; |
assign wb_cbe_out = wb_cbe ; |
assign wbw_fifo_wenable_out = wbw_fifo_wenable ; //write enable for WBW_FIFO |
assign wbw_fifo_control_out = wbw_fifo_control ; //control bus output for WBW_FIFO |
assign wbr_fifo_renable_out = wbr_fifo_renable ; //read enable for wbr_fifo |
`endif |
|
endmodule //WB_SLAVE |
/verilog/pci_sync_module.v
0,0 → 1,164
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "sync_module.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2003/03/26 13:16:18 mihad |
// Added the reset value parameter to the synchronizer flop module. |
// Added resets to all synchronizer flop instances. |
// Repaired initial sync value in fifos. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.1 2002/02/01 14:43:31 mihad |
// *** empty log message *** |
// |
// |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_sync_module |
( |
set_clk_in, |
delete_clk_in, |
reset_in, |
delete_set_out, |
block_set_out, |
delete_in |
); |
|
// system inputs from two clock domains |
input set_clk_in; |
input delete_clk_in; |
input reset_in; |
// control outputs |
output delete_set_out; |
output block_set_out; |
// control input |
input delete_in; |
|
// internal signals |
reg del_bit; |
wire meta_del_bit; |
reg sync_del_bit; |
reg delayed_del_bit; |
wire meta_bckp_bit; |
reg sync_bckp_bit; |
reg delayed_bckp_bit; |
|
|
// DELETE_IN input FF - when set must be active, until it is sinchronously cleared |
always@(posedge delete_clk_in or posedge reset_in) |
begin |
if (reset_in) |
del_bit <= 1'b0; |
else |
begin |
if (!delayed_bckp_bit && sync_bckp_bit) |
del_bit <= 1'b0; |
else if (delete_in) |
del_bit <= 1'b1; |
end |
end |
assign block_set_out = del_bit; |
|
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(1, 0) delete_sync |
( |
.data_in (del_bit), |
.clk_out (set_clk_in), |
.sync_data_out (meta_del_bit), |
.async_reset (reset_in) |
) ; |
|
// Final synchronization of del_bit signal to the set clock domain |
always@(posedge set_clk_in or posedge reset_in) |
begin |
if (reset_in) |
sync_del_bit <= 1'b0; |
else |
sync_del_bit <= meta_del_bit; |
end |
|
// Delayed sync_del_bit signal for one clock period pulse generation |
always@(posedge set_clk_in or posedge reset_in) |
begin |
if (reset_in) |
delayed_del_bit <= 1'b0; |
else |
delayed_del_bit <= sync_del_bit; |
end |
|
assign delete_set_out = !delayed_del_bit && sync_del_bit; |
|
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(1, 0) clear_delete_sync |
( |
.data_in (sync_del_bit), |
.clk_out (delete_clk_in), |
.sync_data_out (meta_bckp_bit), |
.async_reset (reset_in) |
) ; |
|
// Final synchronization of sync_del_bit signal to the delete clock domain |
always@(posedge delete_clk_in or posedge reset_in) |
begin |
if (reset_in) |
sync_bckp_bit <= 1'b0; |
else |
sync_bckp_bit <= meta_bckp_bit; |
end |
|
// Delayed sync_bckp_bit signal for one clock period pulse generation |
always@(posedge delete_clk_in or posedge reset_in) |
begin |
if (reset_in) |
delayed_bckp_bit <= 1'b0; |
else |
delayed_bckp_bit <= sync_bckp_bit; |
end |
|
endmodule |
/verilog/pci_wbr_fifo_control.v
0,0 → 1,267
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "wbr_fifo_control.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2003/07/29 08:20:11 mihad |
// Found and simulated the problem in the synchronization logic. |
// Repaired the synchronization logic in the FIFOs. |
// |
// Revision 1.2 2003/03/26 13:16:18 mihad |
// Added the reset value parameter to the synchronizer flop module. |
// Added resets to all synchronizer flop instances. |
// Repaired initial sync value in fifos. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.6 2002/11/27 20:36:12 mihad |
// Changed the code a bit to make it more readable. |
// Functionality not changed in any way. |
// More robust synchronization in fifos is still pending. |
// |
// Revision 1.5 2002/09/30 16:03:04 mihad |
// Added meta flop module for easier meta stable FF identification during synthesis |
// |
// Revision 1.4 2002/09/25 15:53:52 mihad |
// Removed all logic from asynchronous reset network |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
/* FIFO_CONTROL module provides read/write address and status generation for |
FIFOs implemented with standard dual port SRAM cells in ASIC or FPGA designs */ |
`include "pci_constants.v" |
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_wbr_fifo_control |
( |
rclock_in, |
wclock_in, |
renable_in, |
wenable_in, |
reset_in, |
flush_in, |
empty_out, |
waddr_out, |
raddr_out, |
rallow_out, |
wallow_out |
) ; |
|
parameter ADDR_LENGTH = 7 ; |
|
// independent clock inputs - rclock_in = read clock, wclock_in = write clock |
input rclock_in, wclock_in; |
|
// enable inputs - read address changes on rising edge of rclock_in when reads are allowed |
// write address changes on rising edge of wclock_in when writes are allowed |
input renable_in, wenable_in; |
|
// reset input |
input reset_in; |
|
// flush input |
input flush_in ; |
|
// empty status output |
output empty_out; |
|
// read and write addresses outputs |
output [(ADDR_LENGTH - 1):0] waddr_out, raddr_out; |
|
// read and write allow outputs |
output rallow_out, wallow_out ; |
|
// read address register |
reg [(ADDR_LENGTH - 1):0] raddr ; |
|
// write address register |
reg [(ADDR_LENGTH - 1):0] waddr; |
assign waddr_out = waddr ; |
|
// grey code register |
reg [(ADDR_LENGTH - 1):0] wgrey_addr ; |
|
// next write gray address calculation - bitwise xor between address and shifted address |
wire [(ADDR_LENGTH - 2):0] calc_wgrey_next = waddr[(ADDR_LENGTH - 1):1] ^ waddr[(ADDR_LENGTH - 2):0] ; |
|
// grey code register |
reg [(ADDR_LENGTH - 1):0] rgrey_addr ; |
|
// next read gray address calculation - bitwise xor between address and shifted address |
wire [(ADDR_LENGTH - 2):0] calc_rgrey_next = raddr[(ADDR_LENGTH - 1):1] ^ raddr[(ADDR_LENGTH - 2):0] ; |
|
// FF for registered empty flag |
wire empty ; |
|
// write allow wire |
wire wallow = wenable_in ; |
|
// write allow output assignment |
assign wallow_out = wallow ; |
|
// read allow wire |
wire rallow ; |
|
// clear generation for FFs and registers |
wire clear = reset_in /*|| flush_in*/ ; // flush changed to synchronous operation |
|
assign empty_out = empty ; |
|
//rallow generation |
assign rallow = renable_in && !empty ; // reads allowed if read enable is high and FIFO is not empty |
|
// rallow output assignment |
assign rallow_out = renable_in ; |
|
// at any clock edge that rallow is high, this register provides next read address, so wait cycles are not necessary |
// when FIFO is empty, this register provides actual read address, so first location can be read |
reg [(ADDR_LENGTH - 1):0] raddr_plus_one ; |
|
// address output mux - when FIFO is empty, current actual address is driven out, when it is non - empty next address is driven out |
// done for zero wait state burst |
assign raddr_out = rallow ? raddr_plus_one : raddr ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
raddr_plus_one <= #`FF_DELAY 2 ; |
raddr <= #`FF_DELAY 1 ; |
end |
else if (flush_in) |
begin |
raddr_plus_one <= #`FF_DELAY waddr + 1'b1 ; |
raddr <= #`FF_DELAY waddr ; |
end |
else if (rallow) |
begin |
raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ; |
raddr <= #`FF_DELAY raddr_plus_one ; |
end |
end |
|
/*----------------------------------------------------------------------------------------------- |
Read address control consists of Read address counter and Grey Address register |
--------------------------------------------------------------------------------------------------*/ |
// grey coded address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
rgrey_addr <= #`FF_DELAY 0 ; |
end |
else if (flush_in) |
begin |
rgrey_addr <= #`FF_DELAY wgrey_addr ; // when flushed, copy value from write side |
end |
else if (rallow) |
begin |
rgrey_addr <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ; |
end |
end |
|
/*-------------------------------------------------------------------------------------------- |
Write address control consists of write address counter and Grey Code Register |
----------------------------------------------------------------------------------------------*/ |
// grey coded address for status generation in write clock domain |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
wgrey_addr <= #1 0 ; |
end |
else |
if (wallow) |
begin |
wgrey_addr <= #1 {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ; |
end |
end |
|
// write address counter - nothing special except initial value |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
// initial value is 1 |
waddr <= #`FF_DELAY 1 ; |
else |
if (wallow) |
waddr <= #`FF_DELAY waddr + 1'b1 ; |
end |
|
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Empty control: |
Gray coded write address pointer is synchronized to read clock domain and compared to Gray coded read address pointer. |
If they are equal, fifo is empty. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
wire [(ADDR_LENGTH - 1):0] rclk_sync_wgrey_addr ; |
reg [(ADDR_LENGTH - 1):0] rclk_wgrey_addr ; |
pci_synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_wgrey_addr |
( |
.data_in (wgrey_addr), |
.clk_out (rclock_in), |
.sync_data_out (rclk_sync_wgrey_addr), |
.async_reset (clear) |
) ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
rclk_wgrey_addr <= #`FF_DELAY 0 ; |
else |
rclk_wgrey_addr <= #`FF_DELAY rclk_sync_wgrey_addr ; |
end |
|
assign empty = (rgrey_addr == rclk_wgrey_addr) ; |
endmodule |
/verilog/pci_pcir_fifo_control.v
0,0 → 1,333
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "fifo_control.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2003/07/29 08:20:11 mihad |
// Found and simulated the problem in the synchronization logic. |
// Repaired the synchronization logic in the FIFOs. |
// |
// Revision 1.2 2003/03/26 13:16:18 mihad |
// Added the reset value parameter to the synchronizer flop module. |
// Added resets to all synchronizer flop instances. |
// Repaired initial sync value in fifos. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.7 2002/11/27 20:36:10 mihad |
// Changed the code a bit to make it more readable. |
// Functionality not changed in any way. |
// More robust synchronization in fifos is still pending. |
// |
// Revision 1.6 2002/09/30 16:03:04 mihad |
// Added meta flop module for easier meta stable FF identification during synthesis |
// |
// Revision 1.5 2002/09/25 15:53:52 mihad |
// Removed all logic from asynchronous reset network |
// |
// Revision 1.4 2002/03/05 11:53:47 mihad |
// Added some testcases, removed un-needed fifo signals |
// |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
/* FIFO_CONTROL module provides read/write address and status generation for |
FIFOs implemented with standard dual port SRAM cells in ASIC or FPGA designs */ |
|
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_pcir_fifo_control |
( |
rclock_in, |
wclock_in, |
renable_in, |
wenable_in, |
reset_in, |
flush_in, |
full_out, |
almost_empty_out, |
empty_out, |
waddr_out, |
raddr_out, |
rallow_out, |
wallow_out |
); |
|
// address length parameter - depends on fifo depth |
parameter ADDR_LENGTH = 7 ; |
|
// independent clock inputs - rclock_in = read clock, wclock_in = write clock |
input rclock_in, wclock_in; |
|
// enable inputs - read address changes on rising edge of rclock_in when reads are allowed |
// write address changes on rising edge of wclock_in when writes are allowed |
input renable_in, wenable_in; |
|
// reset input |
input reset_in; |
|
// flush input |
input flush_in ; |
|
// almost empy status output |
output almost_empty_out; |
|
// full and empty status outputs |
output full_out, empty_out; |
|
// read and write addresses outputs |
output [(ADDR_LENGTH - 1):0] waddr_out, raddr_out; |
|
// read and write allow outputs |
output rallow_out, wallow_out ; |
|
// read address register |
reg [(ADDR_LENGTH - 1):0] raddr ; |
|
// write address register |
reg [(ADDR_LENGTH - 1):0] waddr; |
assign waddr_out = waddr ; |
|
// grey code registers |
// grey code pipeline for write address |
reg [(ADDR_LENGTH - 1):0] wgrey_addr ; // current grey coded write address |
reg [(ADDR_LENGTH - 1):0] wgrey_next ; // next grey coded write address |
|
// next write gray address calculation - bitwise xor between address and shifted address |
wire [(ADDR_LENGTH - 2):0] calc_wgrey_next = waddr[(ADDR_LENGTH - 1):1] ^ waddr[(ADDR_LENGTH - 2):0] ; |
|
// grey code pipeline for read address |
reg [(ADDR_LENGTH - 1):0] rgrey_addr ; // current |
reg [(ADDR_LENGTH - 1):0] rgrey_next ; // next |
|
// next read gray address calculation - bitwise xor between address and shifted address |
wire [(ADDR_LENGTH - 2):0] calc_rgrey_next = raddr[(ADDR_LENGTH - 1):1] ^ raddr[(ADDR_LENGTH - 2):0] ; |
|
// FFs for registered empty and full flags |
wire empty ; |
wire full ; |
|
// almost_empty tag |
wire almost_empty ; |
|
// write allow wire - writes are allowed when fifo is not full |
wire wallow = wenable_in && !full ; |
|
// write allow output assignment |
assign wallow_out = wallow ; |
|
// read allow wire |
wire rallow ; |
|
// full output assignment |
assign full_out = full ; |
|
// clear generation for FFs and registers |
wire clear = reset_in /*|| flush_in*/ ; // flush changed to synchronous operation |
|
assign empty_out = empty ; |
|
//rallow generation |
assign rallow = renable_in && !empty ; // reads allowed if read enable is high and FIFO is not empty |
|
// rallow output assignment |
assign rallow_out = rallow ; |
|
// almost empty output assignment |
assign almost_empty_out = almost_empty ; |
|
// at any clock edge that rallow is high, this register provides next read address, so wait cycles are not necessary |
// when FIFO is empty, this register provides actual read address, so first location can be read |
reg [(ADDR_LENGTH - 1):0] raddr_plus_one ; |
|
// address output mux - when FIFO is not read, current actual address is driven out, when it is read, next address is driven out to provide |
// next data immediately |
// done for zero wait state burst operation |
assign raddr_out = rallow ? raddr_plus_one : raddr ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial values seem a bit odd - they are this way to allow easier grey pipeline implementation and to allow min fifo size of 8 |
raddr_plus_one <= #`FF_DELAY 3 ; |
raddr <= #`FF_DELAY 2 ; |
end |
else if (flush_in) |
begin |
raddr_plus_one <= #`FF_DELAY waddr + 1'b1 ; |
raddr <= #`FF_DELAY waddr ; |
end |
else if (rallow) |
begin |
raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ; |
raddr <= #`FF_DELAY raddr_plus_one ; |
end |
end |
|
/*----------------------------------------------------------------------------------------------- |
Read address control consists of Read address counter and Grey Address pipeline |
There are 2 Grey addresses: |
- rgrey_addr is Grey Code of current read address |
- rgrey_next is Grey Code of next read address |
--------------------------------------------------------------------------------------------------*/ |
// grey coded address pipeline for status generation in read clock domain |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
rgrey_addr <= #1 0 ; |
rgrey_next <= #`FF_DELAY 1 ; // this grey code is calculated from the current binary address and loaded any time data is read from fifo |
end |
else if (flush_in) |
begin |
// when fifo is flushed, load the register values from the write clock domain. |
// must be no problem, because write pointers are stable for at least 3 clock cycles before flush can occur. |
rgrey_addr <= #1 wgrey_addr ; |
rgrey_next <= #`FF_DELAY wgrey_next ; |
end |
else if (rallow) |
begin |
// move the pipeline when data is read from fifo and calculate new value for first stage of pipeline from current binary fifo address |
rgrey_addr <= #1 rgrey_next ; |
rgrey_next <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ; |
end |
end |
|
/*-------------------------------------------------------------------------------------------- |
Write address control consists of write address counter and 2 Grey Code Registers: |
- wgrey_addr represents current Grey Coded write address |
- wgrey_next represents Grey Coded next write address |
----------------------------------------------------------------------------------------------*/ |
// grey coded address pipeline for status generation in write clock domain |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
wgrey_addr <= #1 0 ; |
wgrey_next <= #`FF_DELAY 1 ; |
end |
else |
if (wallow) |
begin |
wgrey_addr <= #1 wgrey_next ; |
wgrey_next <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ; |
end |
end |
|
// write address binary counter - nothing special except initial value |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
// initial value 2 |
waddr <= #`FF_DELAY 2 ; |
else |
if (wallow) |
waddr <= #`FF_DELAY waddr + 1'b1 ; |
end |
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Full control: |
Gray coded read address pointer is synchronized to write clock domain and compared to Gray coded next write address. |
If they are equal, fifo is full. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_addr ; |
reg [(ADDR_LENGTH - 1):0] wclk_rgrey_addr ; |
pci_synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_rgrey_addr |
( |
.data_in (rgrey_addr), |
.clk_out (wclock_in), |
.sync_data_out (wclk_sync_rgrey_addr), |
.async_reset (clear) |
) ; |
|
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
wclk_rgrey_addr <= #`FF_DELAY 0 ; |
else |
wclk_rgrey_addr <= #`FF_DELAY wclk_sync_rgrey_addr ; |
end |
|
assign full = (wgrey_next == wclk_rgrey_addr) ; |
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Empty control: |
Gray coded write address pointer is synchronized to read clock domain and compared to Gray coded read address pointer. |
If they are equal, fifo is empty. Synchronized write pointer is also compared to Gray coded next read address. If these two are |
equal, fifo is almost empty. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
wire [(ADDR_LENGTH - 1):0] rclk_sync_wgrey_addr ; |
reg [(ADDR_LENGTH - 1):0] rclk_wgrey_addr ; |
pci_synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_wgrey_addr |
( |
.data_in (wgrey_addr), |
.clk_out (rclock_in), |
.sync_data_out (rclk_sync_wgrey_addr), |
.async_reset (clear) |
) ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
rclk_wgrey_addr <= #`FF_DELAY 0 ; |
else |
rclk_wgrey_addr <= #`FF_DELAY rclk_sync_wgrey_addr ; |
end |
|
assign almost_empty = (rgrey_next == rclk_wgrey_addr) ; |
assign empty = (rgrey_addr == rclk_wgrey_addr) ; |
|
endmodule |
/verilog/pci_conf_space.v
0,0 → 1,3364
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: conf_space.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - tadej@opencores.org //// |
//// - Tadej Markovic //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2003/03/26 13:16:18 mihad |
// Added the reset value parameter to the synchronizer flop module. |
// Added resets to all synchronizer flop instances. |
// Repaired initial sync value in fifos. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.4 2002/08/13 11:03:53 mihad |
// Added a few testcases. Repaired wrong reset value for PCI_AM5 register. Repaired Parity Error Detected bit setting. Changed PCI_AM0 to always enabled(regardles of PCI_AM0 define), if image 0 is used as configuration image |
// |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
/*----------------------------------------------------------------------------------------------------------- |
w_ prefix is a sign for Write (and read) side of Dual-Port registers |
r_ prefix is a sign for Read only side of Dual-Port registers |
In the first line there are DATA and ADDRESS ports, in the second line there are write enable and read |
enable signals with chip-select (conf_hit) for config. space. |
In the third line there are output signlas from Command register of the PCI configuration header !!! |
In the fourth line there are input signals to Status register of the PCI configuration header !!! |
In the fifth line there is output from Latency Timer & r_Interrupt pin registers of the PCI conf. header !!! |
Following are IMAGE specific registers, from which PCI_BASE_ADDR registers are the same as base address |
registers from the PCI conf. header !!! |
-----------------------------------------------------------------------------------------------------------*/ |
// normal R/W address, data and control |
module pci_conf_space |
( w_conf_address_in, w_conf_data_in, w_conf_data_out, r_conf_address_in, r_conf_data_out, |
w_we, w_re, r_re, w_byte_en, w_clock, reset, pci_clk, wb_clk, |
// outputs from command register of the PCI header |
serr_enable, perr_response, pci_master_enable, memory_space_enable, io_space_enable, |
// inputs to status register of the PCI header |
perr_in, serr_in, master_abort_recv, target_abort_recv, target_abort_set, master_data_par_err, |
// output from cache_line_size, latency timer and r_interrupt_pin register of the PCI header |
cache_line_size_to_pci, cache_line_size_to_wb, cache_lsize_not_zero_to_wb, |
latency_tim, |
// output from all pci IMAGE registers |
pci_base_addr0, pci_base_addr1, pci_base_addr2, pci_base_addr3, pci_base_addr4, pci_base_addr5, |
pci_memory_io0, pci_memory_io1, pci_memory_io2, pci_memory_io3, pci_memory_io4, pci_memory_io5, |
pci_addr_mask0, pci_addr_mask1, pci_addr_mask2, pci_addr_mask3, pci_addr_mask4, pci_addr_mask5, |
pci_tran_addr0, pci_tran_addr1, pci_tran_addr2, pci_tran_addr3, pci_tran_addr4, pci_tran_addr5, |
pci_img_ctrl0, pci_img_ctrl1, pci_img_ctrl2, pci_img_ctrl3, pci_img_ctrl4, pci_img_ctrl5, |
// input to pci error control and status register, error address and error data registers |
pci_error_be, pci_error_bc, pci_error_rty_exp, pci_error_es, pci_error_sig, pci_error_addr, |
pci_error_data, |
// output from all wishbone IMAGE registers |
wb_base_addr0, wb_base_addr1, wb_base_addr2, wb_base_addr3, wb_base_addr4, wb_base_addr5, |
wb_memory_io0, wb_memory_io1, wb_memory_io2, wb_memory_io3, wb_memory_io4, wb_memory_io5, |
wb_addr_mask0, wb_addr_mask1, wb_addr_mask2, wb_addr_mask3, wb_addr_mask4, wb_addr_mask5, |
wb_tran_addr0, wb_tran_addr1, wb_tran_addr2, wb_tran_addr3, wb_tran_addr4, wb_tran_addr5, |
wb_img_ctrl0, wb_img_ctrl1, wb_img_ctrl2, wb_img_ctrl3, wb_img_ctrl4, wb_img_ctrl5, |
// input to wb error control and status register, error address and error data registers |
wb_error_be, wb_error_bc, wb_error_rty_exp, wb_error_es, wb_error_sig, wb_error_addr, wb_error_data, |
// output from conf. cycle generation register (sddress), int. control register & interrupt output |
config_addr, icr_soft_res, int_out, |
// input to interrupt status register |
isr_sys_err_int, isr_par_err_int, isr_int_prop ) ; |
|
|
/*########################################################################################################### |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
Input and output ports |
====================== |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
###########################################################################################################*/ |
|
// output data |
output [31 : 0] w_conf_data_out ; |
output [31 : 0] r_conf_data_out ; |
reg [31 : 0] w_conf_data_out ; |
|
`ifdef NO_CNF_IMAGE |
`else |
reg [31 : 0] r_conf_data_out ; |
`endif |
|
// input data |
input [31 : 0] w_conf_data_in ; |
wire [31 : 0] w_conf_pdata_reduced ; // reduced data written into PCI image registers |
wire [31 : 0] w_conf_wdata_reduced ; // reduced data written into WB image registers |
// input address |
input [11 : 0] w_conf_address_in ; |
input [11 : 0] r_conf_address_in ; |
// input control signals |
input w_we ; |
input w_re ; |
input r_re ; |
input [3 : 0] w_byte_en ; |
input w_clock ; |
input reset ; |
input pci_clk ; |
input wb_clk ; |
// PCI header outputs from command register |
output serr_enable ; |
output perr_response ; |
output pci_master_enable ; |
output memory_space_enable ; |
output io_space_enable ; |
// PCI header inputs to status register |
input perr_in ; |
input serr_in ; |
input master_abort_recv ; |
input target_abort_recv ; |
input target_abort_set ; |
input master_data_par_err ; |
// PCI header output from cache_line_size, latency timer and interrupt pin |
output [7 : 0] cache_line_size_to_pci ; // sinchronized to PCI clock |
output [7 : 0] cache_line_size_to_wb ; // sinchronized to WB clock |
output cache_lsize_not_zero_to_wb ; // used in WBU and PCIU |
output [7 : 0] latency_tim ; |
//output [2 : 0] int_pin ; // only 3 LSbits are important! |
// PCI output from image registers |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr0 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr1 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr2 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr3 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr4 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr5 ; |
output pci_memory_io0 ; |
output pci_memory_io1 ; |
output pci_memory_io2 ; |
output pci_memory_io3 ; |
output pci_memory_io4 ; |
output pci_memory_io5 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask0 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask1 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask2 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask3 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask4 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask5 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr0 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr1 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr2 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr3 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr4 ; |
output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr5 ; |
output [2 : 1] pci_img_ctrl0 ; |
output [2 : 1] pci_img_ctrl1 ; |
output [2 : 1] pci_img_ctrl2 ; |
output [2 : 1] pci_img_ctrl3 ; |
output [2 : 1] pci_img_ctrl4 ; |
output [2 : 1] pci_img_ctrl5 ; |
// PCI input to pci error control and status register, error address and error data registers |
input [3 : 0] pci_error_be ; |
input [3 : 0] pci_error_bc ; |
input pci_error_rty_exp ; |
input pci_error_es ; |
input pci_error_sig ; |
input [31 : 0] pci_error_addr ; |
input [31 : 0] pci_error_data ; |
// WISHBONE output from image registers |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr0 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr1 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr2 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr3 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr4 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr5 ; |
output wb_memory_io0 ; |
output wb_memory_io1 ; |
output wb_memory_io2 ; |
output wb_memory_io3 ; |
output wb_memory_io4 ; |
output wb_memory_io5 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask0 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask1 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask2 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask3 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask4 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask5 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr0 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr1 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr2 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr3 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr4 ; |
output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr5 ; |
output [2 : 0] wb_img_ctrl0 ; |
output [2 : 0] wb_img_ctrl1 ; |
output [2 : 0] wb_img_ctrl2 ; |
output [2 : 0] wb_img_ctrl3 ; |
output [2 : 0] wb_img_ctrl4 ; |
output [2 : 0] wb_img_ctrl5 ; |
// WISHBONE input to wb error control and status register, error address and error data registers |
input [3 : 0] wb_error_be ; |
input [3 : 0] wb_error_bc ; |
input wb_error_rty_exp ; |
input wb_error_es ; |
input wb_error_sig ; |
input [31 : 0] wb_error_addr ; |
input [31 : 0] wb_error_data ; |
// GENERAL output from conf. cycle generation register & int. control register |
output [23 : 0] config_addr ; |
output icr_soft_res ; |
output int_out ; |
// GENERAL input to interrupt status register |
input isr_sys_err_int ; |
input isr_par_err_int ; |
input isr_int_prop ; |
|
|
/*########################################################################################################### |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
REGISTERS definition |
==================== |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
###########################################################################################################*/ |
|
// Decoded Register Select signals for writting (only one address decoder) |
reg [55 : 0] w_reg_select_dec ; |
|
/*########################################################################################################### |
------------------------------------------------------------------------------------------------------------- |
PCI CONFIGURATION SPACE HEADER (type 00h) registers |
|
BIST and some other registers are not implemented and therefor written in correct |
place with comment line. There are also some registers with NOT all bits implemented and therefor uses |
_bitX or _bitX2_X1 to sign which bit or range of bits are implemented. |
Some special cases and examples are described below! |
------------------------------------------------------------------------------------------------------------- |
###########################################################################################################*/ |
|
/*----------------------------------------------------------------------------------------------------------- |
[000h-00Ch] First 4 DWORDs (32-bit) of PCI configuration header - the same regardless of the HEADER type ! |
r_ prefix is a sign for read only registers |
Vendor_ID is an ID for a specific vendor defined by PCI_SIG - 2321h does not belong to anyone (e.g. |
Xilinx's Vendor_ID is 10EEh and Altera's Vendor_ID is 1172h). Device_ID and Revision_ID should be used |
together by application. Class_Code has 3 bytes to define BASE class (06h for PCI Bridge), SUB class |
(00h for HOST type, 80h for Other Bridge type) and Interface type (00h for normal). |
-----------------------------------------------------------------------------------------------------------*/ |
parameter r_vendor_id = `HEADER_VENDOR_ID ; // 16'h2321 = 16'd8993 !!! |
parameter r_device_id = `HEADER_DEVICE_ID ; |
reg command_bit8 ; |
reg command_bit6 ; |
reg [2 : 0] command_bit2_0 ; |
reg [15 : 11] status_bit15_11 ; |
parameter r_status_bit10_9 = 2'b01 ; // 2'b01 means MEDIUM devsel timing !!! |
reg status_bit8 ; |
parameter r_status_bit7 = 1'b1 ; // fast back-to-back capable response !!! |
parameter r_status_bit5 = `HEADER_66MHz ; // 1'b0 indicates 33 MHz capable !!! |
parameter r_revision_id = `HEADER_REVISION_ID ; |
`ifdef HOST |
parameter r_class_code = 24'h06_00_00 ; |
`else |
parameter r_class_code = 24'h06_80_00 ; |
`endif |
reg [7 : 0] cache_line_size_reg ; |
reg [7 : 0] latency_timer ; |
parameter r_header_type = 8'h00 ; |
// REG bist NOT implemented !!! |
|
/*----------------------------------------------------------------------------------------------------------- |
[010h-03Ch] all other DWORDs (32-bit) of PCI configuration header - only for HEADER type 00h ! |
r_ prefix is a sign for read only registers |
BASE_ADDRESS_REGISTERS are the same as ones in the PCI Target configuration registers section. They |
are duplicated and therefor defined just ones and used with the same name as written below. If |
IMAGEx is NOT defined there is only parameter image_X assigned to '0' and this parameter is used |
elsewhere in the code. This parameter is defined in the INTERNAL SIGNALS part !!! |
Interrupt_Pin value 8'h01 is used for INT_A pin used. |
MIN_GNT and MAX_LAT are used for device's desired values for Latency Timer value. The value in boath |
registers specifies a period of time in units of 1/4 microsecond. ZERO indicates that there are no |
major requirements for the settings of Latency Timer. |
MIN_GNT specifieshow how long a burst period the device needs at 33MHz. MAX_LAT specifies how often |
the device needs to gain access to the PCI bus. Values are choosen assuming that the target does not |
insert any wait states. Follow the expamle of settings for simple display card. |
If we use 64 (32-bit) FIFO locations for one burst then we need 8 x 1/4 microsecond periods at 33MHz |
clock rate => MIN_GNT = 08h ! Resolution is 1024 x 768 (= 786432 pixels for one frame) with 16-bit |
color mode. We can transfere 2 16-bit pixels in one FIFO location. From that we calculate, that for |
one frame we need 6144 burst transferes in 1/25 second. So we need one burst every 6,51 microsecond |
and that is 26 x 1/4 microsecond or 1Ah x 1/4 microsecond => MAX_LAT = 1Ah ! |
-----------------------------------------------------------------------------------------------------------*/ |
// REG x 6 base_address_register_X IMPLEMENTED as pci_ba_X !!! |
// REG r_cardbus_cis_pointer NOT implemented !!! |
// REG r_subsystem_vendor_id NOT implemented !!! |
// REG r_subsystem_id NOT implemented !!! |
// REG r_expansion_rom_base_address NOT implemented !!! |
// REG r_cap_list_pointer NOT implemented !!! |
reg [7 : 0] interrupt_line ; |
parameter r_interrupt_pin = 8'h01 ; |
parameter r_min_gnt = 8'h08 ; |
parameter r_max_lat = 8'h1a ; |
|
|
/*########################################################################################################### |
------------------------------------------------------------------------------------------------------------- |
PCI Bridge default image SIZE parameters |
This parameters are not part of any register group, but are needed for default image size configuration |
used in PCI Target and WISHBONE Slave configuration registers! |
------------------------------------------------------------------------------------------------------------- |
###########################################################################################################*/ |
|
/*----------------------------------------------------------------------------------------------------------- |
PCI Target default image size parameters are defined with masked bits for address mask registers of |
each image space. By default there are 1MByte of address space defined for def_pci_imageX_addr_map |
parameters! |
-----------------------------------------------------------------------------------------------------------*/ |
wire [19:0] def_pci_image0_addr_map = `PCI_AM0 ; |
wire [19:0] def_pci_image1_addr_map = `PCI_AM1 ; |
wire [19:0] def_pci_image2_addr_map = `PCI_AM2 ; |
wire [19:0] def_pci_image3_addr_map = `PCI_AM3 ; |
wire [19:0] def_pci_image4_addr_map = `PCI_AM4 ; |
wire [19:0] def_pci_image5_addr_map = `PCI_AM5 ; |
|
/*----------------------------------------------------------------------------------------------------------- |
WISHBONE Slave default image size parameters are defined with masked bits for address mask registers |
of each image space. By default there are 1MByte of address space defined for def_wb_imageX_addr_map |
parameters except for def_wb_image0_addr_map which is used for configuration space! |
-----------------------------------------------------------------------------------------------------------*/ |
// PARAMETER def_wb_image0_addr_map IMPLEMENTED as r_wb_am0 parameter for CONF. space !!! |
wire [19:0] def_wb_image1_addr_map = 20'h0000_0 ; |
wire [19:0] def_wb_image2_addr_map = 20'h0000_0 ; |
wire [19:0] def_wb_image3_addr_map = 20'h0000_0 ; |
wire [19:0] def_wb_image4_addr_map = 20'h0000_0 ; |
wire [19:0] def_wb_image5_addr_map = 20'h0000_0 ; |
|
|
/*########################################################################################################### |
------------------------------------------------------------------------------------------------------------- |
PCI Target configuration registers |
There are also some registers with NOT all bits implemented and therefor uses _bitX or _bitX2_X1 to |
sign which bit or range of bits are implemented. Some special cases and examples are described below! |
------------------------------------------------------------------------------------------------------------- |
###########################################################################################################*/ |
|
/*----------------------------------------------------------------------------------------------------------- |
[100h-168h] |
Depending on defines (PCI_IMAGE1 or .. or PCI_IMAGE5 or (PCI_IMAGE0 and HOST)) in constants.v file, |
there are registers corresponding to each IMAGE defined to REG and parameter pci_image_X assigned to '1'. |
The maximum number of images is "6". By default there are first two images used and the first (PCI_IMAGE0) |
is assigned to Configuration space! With a 'define' PCI_IMAGEx you choose the number of used PCI IMAGES |
in a bridge without PCI_IMAGE0 (e.g. PCI_IMAGE3 tells, that PCI_IMAGE1, PCI_IMAGE2 and PCI_IMAGE3 are |
used for mapping the space from WB to PCI. Offcourse, PCI_IMAGE0 is assigned to Configuration space). |
That leave us PCI_IMAGE5 as the maximum number of images. |
There is one exeption, when the core is implemented as HOST. If so, then the PCI specification allowes |
the Configuration space NOT to be visible on the PCI bus. With `define PCI_IMAGE0 (and `define HOST), we |
assign PCI_IMAGE0 to normal WB to PCI image and not to configuration space! |
|
When error occurs, PCI ERR_ADDR and ERR_DATA registers stores address and data on the bus that |
caused error. While ERR_CS register stores Byte Enables and Bus Command in the MSByte. In bits 10 |
and 8 it reports Retry Counter Expired (for posted writes), Error Source (Master Abort) and Error |
Report Signal (signals that error has occured) respectively. With bit 0 we enable Error Reporting |
mechanism. |
-----------------------------------------------------------------------------------------------------------*/ |
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
`ifdef PCI_IMAGE0 // if PCI bridge is HOST and IMAGE0 is assigned as general image space |
reg [31 : 12] pci_ba0_bit31_12 ; |
reg [2 : 1] pci_img_ctrl0_bit2_1 ; |
reg pci_ba0_bit0 ; |
reg [31 : 12] pci_am0 ; |
reg [31 : 12] pci_ta0 ; |
`else // if PCI bridge is HOST and IMAGE0 is not used |
wire [31 : 12] pci_ba0_bit31_12 = 20'h0000_0 ; // NO base address needed |
wire [2 : 1] pci_img_ctrl0_bit2_1 = 2'b00 ; // NO addr.transl. and pre-fetch |
wire pci_ba0_bit0 = 0 ; // config. space is MEMORY space |
wire [31 : 12] pci_am0 = 20'h0000_0 ; // NO address mask needed |
wire [31 : 12] pci_ta0 = 20'h0000_0 ; // NO address translation needed |
`endif |
`else // if PCI bridge is HOST and IMAGE0 is assigned to PCI configuration space |
reg [31 : 12] pci_ba0_bit31_12 ; |
wire [2 : 1] pci_img_ctrl0_bit2_1 = 2'b00 ; // NO pre-fetch and read line support |
wire pci_ba0_bit0 = 0 ; // config. space is MEMORY space |
wire [31 : 12] pci_am0 = 20'hFFFF_F ; // address mask for configuration image always 20'hffff_f |
wire [31 : 12] pci_ta0 = 20'h0000_0 ; // NO address translation needed |
`endif |
`else // if PCI bridge is GUEST, then IMAGE0 is assigned to PCI configuration space |
reg [31 : 12] pci_ba0_bit31_12 ; |
wire [2 : 1] pci_img_ctrl0_bit2_1 = 2'b00 ; // NO addr.transl. and pre-fetch |
wire pci_ba0_bit0 = 0 ; // config. space is MEMORY space |
wire [31 : 12] pci_am0 = 20'hffff_f ; // address mask for configuration image always 20'hffff_f |
wire [31 : 12] pci_ta0 = 20'h0000_0 ; // NO address translation needed |
`endif |
// IMAGE1 is included by default, meanwhile other IMAGEs are optional !!! |
reg [2 : 1] pci_img_ctrl1_bit2_1 ; |
reg [31 : 12] pci_ba1_bit31_12 ; |
`ifdef HOST |
reg pci_ba1_bit0 ; |
`else |
wire pci_ba1_bit0 = `PCI_BA1_MEM_IO ; |
`endif |
reg [31 : 12] pci_am1 ; |
reg [31 : 12] pci_ta1 ; |
`ifdef PCI_IMAGE2 |
reg [2 : 1] pci_img_ctrl2_bit2_1 ; |
reg [31 : 12] pci_ba2_bit31_12 ; |
`ifdef HOST |
reg pci_ba2_bit0 ; |
`else |
wire pci_ba2_bit0 = `PCI_BA2_MEM_IO ; |
`endif |
reg [31 : 12] pci_am2 ; |
reg [31 : 12] pci_ta2 ; |
`else |
wire [2 : 1] pci_img_ctrl2_bit2_1 = 2'b00 ; |
wire [31 : 12] pci_ba2_bit31_12 = 20'h0000_0 ; |
wire pci_ba2_bit0 = 1'b0 ; |
wire [31 : 12] pci_am2 = 20'h0000_0 ; |
wire [31 : 12] pci_ta2 = 20'h0000_0 ; |
`endif |
`ifdef PCI_IMAGE3 |
reg [2 : 1] pci_img_ctrl3_bit2_1 ; |
reg [31 : 12] pci_ba3_bit31_12 ; |
`ifdef HOST |
reg pci_ba3_bit0 ; |
`else |
wire pci_ba3_bit0 = `PCI_BA3_MEM_IO ; |
`endif |
reg [31 : 12] pci_am3 ; |
reg [31 : 12] pci_ta3 ; |
`else |
wire [2 : 1] pci_img_ctrl3_bit2_1 = 2'b00 ; |
wire [31 : 12] pci_ba3_bit31_12 = 20'h0000_0 ; |
wire pci_ba3_bit0 = 1'b0 ; |
wire [31 : 12] pci_am3 = 20'h0000_0 ; |
wire [31 : 12] pci_ta3 = 20'h0000_0 ; |
`endif |
`ifdef PCI_IMAGE4 |
reg [2 : 1] pci_img_ctrl4_bit2_1 ; |
reg [31 : 12] pci_ba4_bit31_12 ; |
`ifdef HOST |
reg pci_ba4_bit0 ; |
`else |
wire pci_ba4_bit0 = `PCI_BA4_MEM_IO ; |
`endif |
reg [31 : 12] pci_am4 ; |
reg [31 : 12] pci_ta4 ; |
`else |
wire [2 : 1] pci_img_ctrl4_bit2_1 = 2'b00 ; |
wire [31 : 12] pci_ba4_bit31_12 = 20'h0000_0 ; |
wire pci_ba4_bit0 = 1'b0 ; |
wire [31 : 12] pci_am4 = 20'h0000_0 ; |
wire [31 : 12] pci_ta4 = 20'h0000_0 ; |
`endif |
`ifdef PCI_IMAGE5 |
reg [2 : 1] pci_img_ctrl5_bit2_1 ; |
reg [31 : 12] pci_ba5_bit31_12 ; |
`ifdef HOST |
reg pci_ba5_bit0 ; |
`else |
wire pci_ba5_bit0 = `PCI_BA5_MEM_IO ; |
`endif |
reg [31 : 12] pci_am5 ; |
reg [31 : 12] pci_ta5 ; |
`else |
wire [2 : 1] pci_img_ctrl5_bit2_1 = 2'b00 ; |
wire [31 : 12] pci_ba5_bit31_12 = 20'h0000_0 ; |
wire pci_ba5_bit0 = 1'b0 ; |
wire [31 : 12] pci_am5 = 20'h0000_0 ; |
wire [31 : 12] pci_ta5 = 20'h0000_0 ; |
`endif |
reg [31 : 24] pci_err_cs_bit31_24 ; |
reg pci_err_cs_bit10 ; |
reg pci_err_cs_bit9 ; |
reg pci_err_cs_bit8 ; |
reg pci_err_cs_bit0 ; |
reg [31 : 0] pci_err_addr ; |
reg [31 : 0] pci_err_data ; |
|
|
/*########################################################################################################### |
------------------------------------------------------------------------------------------------------------- |
WISHBONE Slave configuration registers |
There are also some registers with NOT all bits implemented and therefor uses _bitX or _bitX2_X1 to |
sign which bit or range of bits are implemented. Some special cases and examples are described below! |
------------------------------------------------------------------------------------------------------------- |
###########################################################################################################*/ |
|
/*----------------------------------------------------------------------------------------------------------- |
[800h-85Ch] |
Depending on defines (WB_IMAGE1 or .. or WB_IMAGE4 or WB_IMAGE5) in constants.v file, there are |
registers corresponding to each IMAGE defined to REG and parameter wb_image_X assigned to '1'. |
The maximum number of images is "6". By default there are first two images used and the first (WB_IMAGE0) |
is assigned to Configuration space! With a 'define' WB_IMAGEx you choose the number of used WB IMAGES in |
a bridge without WB_IMAGE0 (e.g. WB_IMAGE3 tells, that WB_IMAGE1, WB_IMAGE2 and WB_IMAGE3 are used for |
mapping the space from PCI to WB. Offcourse, WB_IMAGE0 is assigned to Configuration space). That leave |
us WB_IMAGE5 as the maximum number of images. |
|
When error occurs, WISHBONE ERR_ADDR and ERR_DATA registers stores address and data on the bus that |
caused error. While ERR_CS register stores Byte Enables and Bus Command in the MSByte. In bits 10, 9 |
and 8 it reports Retry Counter Expired (for posted writes), Error Source (Master Abort) and Error |
Report Signal (signals that error has occured) respectively. With bit 0 we enable Error Reporting |
mechanism. |
-----------------------------------------------------------------------------------------------------------*/ |
// WB_IMAGE0 is always assigned to config. space or is not used |
wire [2 : 0] wb_img_ctrl0_bit2_0 = 3'b000 ; // NO addr.transl., pre-fetch and read-line |
wire [31 : 12] wb_ba0_bit31_12 = `WB_CONFIGURATION_BASE ; |
wire wb_ba0_bit0 = 0 ; // config. space is MEMORY space |
wire [31 : 12] wb_am0 = `WB_AM0 ; // 4KBytes of configuration space is minimum |
wire [31 : 12] wb_ta0 = 20'h0000_0 ; // NO address translation needed |
// WB_IMAGE1 is included by default meanwhile others are optional ! |
reg [2 : 0] wb_img_ctrl1_bit2_0 ; |
reg [31 : 12] wb_ba1_bit31_12 ; |
reg wb_ba1_bit0 ; |
reg [31 : 12] wb_am1 ; |
reg [31 : 12] wb_ta1 ; |
`ifdef WB_IMAGE2 |
reg [2 : 0] wb_img_ctrl2_bit2_0 ; |
reg [31 : 12] wb_ba2_bit31_12 ; |
reg wb_ba2_bit0 ; |
reg [31 : 12] wb_am2 ; |
reg [31 : 12] wb_ta2 ; |
`else |
wire [2 : 0] wb_img_ctrl2_bit2_0 = 3'b000 ; |
wire [31 : 12] wb_ba2_bit31_12 = 20'h0000_0 ; |
wire wb_ba2_bit0 = 1'b0 ; |
wire [31 : 12] wb_am2 = 20'h0000_0 ; |
wire [31 : 12] wb_ta2 = 20'h0000_0 ; |
`endif |
`ifdef WB_IMAGE3 |
reg [2 : 0] wb_img_ctrl3_bit2_0 ; |
reg [31 : 12] wb_ba3_bit31_12 ; |
reg wb_ba3_bit0 ; |
reg [31 : 12] wb_am3 ; |
reg [31 : 12] wb_ta3 ; |
`else |
wire [2 : 0] wb_img_ctrl3_bit2_0 = 3'b000 ; |
wire [31 : 12] wb_ba3_bit31_12 = 20'h0000_0 ; |
wire wb_ba3_bit0 = 1'b0 ; |
wire [31 : 12] wb_am3 = 20'h0000_0 ; |
wire [31 : 12] wb_ta3 = 20'h0000_0 ; |
`endif |
`ifdef WB_IMAGE4 |
reg [2 : 0] wb_img_ctrl4_bit2_0 ; |
reg [31 : 12] wb_ba4_bit31_12 ; |
reg wb_ba4_bit0 ; |
reg [31 : 12] wb_am4 ; |
reg [31 : 12] wb_ta4 ; |
`else |
wire [2 : 0] wb_img_ctrl4_bit2_0 = 3'b000 ; |
wire [31 : 12] wb_ba4_bit31_12 = 20'h0000_0 ; |
wire wb_ba4_bit0 = 1'b0 ; |
wire [31 : 12] wb_am4 = 20'h0000_0 ; |
wire [31 : 12] wb_ta4 = 20'h0000_0 ; |
`endif |
`ifdef WB_IMAGE5 |
reg [2 : 0] wb_img_ctrl5_bit2_0 ; |
reg [31 : 12] wb_ba5_bit31_12 ; |
reg wb_ba5_bit0 ; |
reg [31 : 12] wb_am5 ; |
reg [31 : 12] wb_ta5 ; |
`else |
wire [2 : 0] wb_img_ctrl5_bit2_0 = 3'b000 ; |
wire [31 : 12] wb_ba5_bit31_12 = 20'h0000_0 ; |
wire wb_ba5_bit0 = 1'b0 ; |
wire [31 : 12] wb_am5 = 20'h0000_0 ; |
wire [31 : 12] wb_ta5 = 20'h0000_0 ; |
`endif |
reg [31 : 24] wb_err_cs_bit31_24 ; |
/* reg wb_err_cs_bit10 ;*/ |
reg wb_err_cs_bit9 ; |
reg wb_err_cs_bit8 ; |
reg wb_err_cs_bit0 ; |
reg [31 : 0] wb_err_addr ; |
reg [31 : 0] wb_err_data ; |
|
|
/*########################################################################################################### |
------------------------------------------------------------------------------------------------------------- |
Configuration Cycle address register |
There are also some registers with NOT all bits implemented and therefor uses _bitX or _bitX2_X1 to |
sign which bit or range of bits are implemented. |
------------------------------------------------------------------------------------------------------------- |
###########################################################################################################*/ |
|
/*----------------------------------------------------------------------------------------------------------- |
[860h-868h] |
PCI bridge must ignore Type 1 configuration cycles (Master Abort) since they are used for PCI to PCI |
bridges. This is single function device, that means responding on configuration cycles to all functions |
(or responding only to function 0). Configuration address register for generating configuration cycles |
is prepared for all options (it includes Bus Number, Device, Function, Offset and Type). |
Interrupt acknowledge register stores interrupt vector data returned during Interrupt Acknowledge cycle. |
-----------------------------------------------------------------------------------------------------------*/ |
`ifdef HOST |
reg [23 : 2] cnf_addr_bit23_2 ; |
reg cnf_addr_bit0 ; |
`else // GUEST |
wire [23 : 2] cnf_addr_bit23_2 = 22'h0 ; |
wire cnf_addr_bit0 = 1'b0 ; |
`endif |
// reg [31 : 0] cnf_data ; IMPLEMENTED elsewhere !!!!! |
// reg [31 : 0] int_ack ; IMPLEMENTED elsewhere !!!!! |
|
|
/*########################################################################################################### |
------------------------------------------------------------------------------------------------------------- |
General Interrupt registers |
There are also some registers with NOT all bits implemented and therefor uses _bitX or _bitX2_X1 to |
sign which bit or range of bits are implemented. |
------------------------------------------------------------------------------------------------------------- |
###########################################################################################################*/ |
|
/*----------------------------------------------------------------------------------------------------------- |
[FF8h-FFCh] |
Bit 31 in the Interrupt Control register is set by software and used to generate SOFT RESET. Other 4 |
bits are used to enable interrupt generations. |
5 LSbits in the Interrupt Status register are indicating System Error Int, Parity Error Int, PCI & WB |
Error Int and Inerrupt respecively. System and Parity errors are implented only in HOST bridge |
implementations! |
-----------------------------------------------------------------------------------------------------------*/ |
reg icr_bit31 ; |
`ifdef HOST |
reg [4 : 3] icr_bit4_3 ; |
reg [4 : 3] isr_bit4_3 ; |
reg [2 : 0] icr_bit2_0 ; |
reg [2 : 0] isr_bit2_0 ; |
`else // GUEST |
wire [4 : 3] icr_bit4_3 = 2'h0 ; |
wire [4 : 3] isr_bit4_3 = 2'h0 ; |
reg [2 : 0] icr_bit2_0 ; |
reg [2 : 0] isr_bit2_0 ; |
`endif |
|
|
/*########################################################################################################### |
------------------------------------------------------------------------------------------------------------- |
|
|
-----------------------------------------------------------------------------------------------------------*/ |
|
`ifdef NO_CNF_IMAGE // if IMAGE0 is assigned as general image space |
|
assign r_conf_data_out = 32'h0000_0000 ; |
|
`else |
|
always@(r_conf_address_in or |
status_bit15_11 or status_bit8 or command_bit8 or command_bit6 or command_bit2_0 or |
latency_timer or cache_line_size_reg or |
pci_ba0_bit31_12 or |
pci_img_ctrl0_bit2_1 or pci_am0 or pci_ta0 or pci_ba0_bit0 or |
pci_img_ctrl1_bit2_1 or pci_am1 or pci_ta1 or pci_ba1_bit31_12 or pci_ba1_bit0 or |
pci_img_ctrl2_bit2_1 or pci_am2 or pci_ta2 or pci_ba2_bit31_12 or pci_ba2_bit0 or |
pci_img_ctrl3_bit2_1 or pci_am3 or pci_ta3 or pci_ba3_bit31_12 or pci_ba3_bit0 or |
pci_img_ctrl4_bit2_1 or pci_am4 or pci_ta4 or pci_ba4_bit31_12 or pci_ba4_bit0 or |
pci_img_ctrl5_bit2_1 or pci_am5 or pci_ta5 or pci_ba5_bit31_12 or pci_ba5_bit0 or |
interrupt_line or |
pci_err_cs_bit31_24 or pci_err_cs_bit10 or pci_err_cs_bit9 or pci_err_cs_bit8 or pci_err_cs_bit0 or |
pci_err_addr or pci_err_data or |
wb_ba0_bit31_12 or wb_ba0_bit0 or |
wb_img_ctrl1_bit2_0 or wb_ba1_bit31_12 or wb_ba1_bit0 or wb_am1 or wb_ta1 or |
wb_img_ctrl2_bit2_0 or wb_ba2_bit31_12 or wb_ba2_bit0 or wb_am2 or wb_ta2 or |
wb_img_ctrl3_bit2_0 or wb_ba3_bit31_12 or wb_ba3_bit0 or wb_am3 or wb_ta3 or |
wb_img_ctrl4_bit2_0 or wb_ba4_bit31_12 or wb_ba4_bit0 or wb_am4 or wb_ta4 or |
wb_img_ctrl5_bit2_0 or wb_ba5_bit31_12 or wb_ba5_bit0 or wb_am5 or wb_ta5 or |
wb_err_cs_bit31_24 or /*wb_err_cs_bit10 or*/ wb_err_cs_bit9 or wb_err_cs_bit8 or wb_err_cs_bit0 or |
wb_err_addr or wb_err_data or |
cnf_addr_bit23_2 or cnf_addr_bit0 or icr_bit31 or icr_bit4_3 or icr_bit2_0 or isr_bit4_3 or isr_bit2_0 |
) |
begin |
case (r_conf_address_in[8]) |
1'b0 : |
begin |
case ({r_conf_address_in[7], r_conf_address_in[6]}) |
2'b00 : |
begin |
// PCI header - configuration space |
case (r_conf_address_in[5:2]) |
4'h0: r_conf_data_out = { r_device_id, r_vendor_id } ; |
4'h1: r_conf_data_out = { status_bit15_11, r_status_bit10_9, status_bit8, r_status_bit7, 1'h0, r_status_bit5, |
5'h00, 7'h00, command_bit8, 1'h0, command_bit6, 3'h0, command_bit2_0 } ; |
4'h2: r_conf_data_out = { r_class_code, r_revision_id } ; |
4'h3: r_conf_data_out = { 8'h00, r_header_type, latency_timer, cache_line_size_reg } ; |
4'h4: |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba0_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba0_bit0 & pci_am0[31]; |
end |
4'h5: |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba1_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba1_bit0 & pci_am1[31]; |
end |
4'h6: |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba2_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba2_bit0 & pci_am2[31]; |
end |
4'h7: |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba3_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba3_bit0 & pci_am3[31]; |
end |
4'h8: |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba4_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba4_bit0 & pci_am4[31]; |
end |
4'h9: |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba5_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba5_bit0 & pci_am5[31]; |
end |
4'hf: r_conf_data_out = { r_max_lat, r_min_gnt, r_interrupt_pin, interrupt_line } ; |
default : r_conf_data_out = 32'h0000_0000 ; |
endcase |
end |
default : |
r_conf_data_out = 32'h0000_0000 ; |
endcase |
end |
default : |
begin |
// PCI target - configuration space |
case (r_conf_address_in[7:2]) |
`P_IMG_CTRL0_ADDR: r_conf_data_out = { 29'h00000000, pci_img_ctrl0_bit2_1, 1'h0 } ; |
`P_BA0_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba0_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba0_bit0 & pci_am0[31]; |
end |
`P_AM0_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_TA0_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_IMG_CTRL1_ADDR: r_conf_data_out = { 29'h00000000, pci_img_ctrl1_bit2_1, 1'h0 } ; |
`P_BA1_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba1_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba1_bit0 & pci_am1[31]; |
end |
`P_AM1_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_TA1_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_IMG_CTRL2_ADDR: r_conf_data_out = { 29'h00000000, pci_img_ctrl2_bit2_1, 1'h0 } ; |
`P_BA2_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba2_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba2_bit0 & pci_am2[31]; |
end |
`P_AM2_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_TA2_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_IMG_CTRL3_ADDR: r_conf_data_out = { 29'h00000000, pci_img_ctrl3_bit2_1, 1'h0 } ; |
`P_BA3_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba3_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba3_bit0 & pci_am3[31]; |
end |
`P_AM3_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_TA3_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_IMG_CTRL4_ADDR: r_conf_data_out = { 29'h00000000, pci_img_ctrl4_bit2_1, 1'h0 } ; |
`P_BA4_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba4_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba4_bit0 & pci_am4[31]; |
end |
`P_AM4_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_TA4_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_IMG_CTRL5_ADDR: r_conf_data_out = { 29'h00000000, pci_img_ctrl5_bit2_1, 1'h0 } ; |
`P_BA5_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba5_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = pci_ba5_bit0 & pci_am5[31]; |
end |
`P_AM5_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_TA5_ADDR : |
begin |
r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`P_ERR_CS_ADDR : r_conf_data_out = { pci_err_cs_bit31_24, 13'h0000, pci_err_cs_bit10, pci_err_cs_bit9, |
pci_err_cs_bit8, 7'h00, pci_err_cs_bit0 } ; |
`P_ERR_ADDR_ADDR : r_conf_data_out = pci_err_addr ; |
`P_ERR_DATA_ADDR : r_conf_data_out = pci_err_data ; |
// WB slave - configuration space |
`WB_CONF_SPC_BAR_ADDR: r_conf_data_out = { wb_ba0_bit31_12, 11'h000, wb_ba0_bit0 } ; |
`W_IMG_CTRL1_ADDR: r_conf_data_out = { 29'h00000000, wb_img_ctrl1_bit2_0 } ; |
`W_BA1_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba1_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & |
wb_am1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = wb_ba1_bit0 ; |
end |
`W_AM1_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`W_TA1_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`W_IMG_CTRL2_ADDR: r_conf_data_out = { 29'h00000000, wb_img_ctrl2_bit2_0 } ; |
`W_BA2_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba2_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & |
wb_am2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = wb_ba2_bit0 ; |
end |
`W_AM2_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`W_TA2_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`W_IMG_CTRL3_ADDR: r_conf_data_out = { 29'h00000000, wb_img_ctrl3_bit2_0 } ; |
`W_BA3_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba3_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & |
wb_am3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = wb_ba3_bit0 ; |
end |
`W_AM3_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`W_TA3_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`W_IMG_CTRL4_ADDR: r_conf_data_out = { 29'h00000000, wb_img_ctrl4_bit2_0 } ; |
`W_BA4_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba4_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & |
wb_am4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = wb_ba4_bit0 ; |
end |
`W_AM4_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`W_TA4_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`W_IMG_CTRL5_ADDR: r_conf_data_out = { 29'h00000000, wb_img_ctrl5_bit2_0 } ; |
`W_BA5_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba5_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & |
wb_am5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
r_conf_data_out[0] = wb_ba5_bit0 ; |
end |
`W_AM5_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`W_TA5_ADDR : |
begin |
r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
end |
`W_ERR_CS_ADDR : r_conf_data_out = { wb_err_cs_bit31_24, /*13*/14'h0000, /*wb_err_cs_bit10,*/ |
wb_err_cs_bit9, wb_err_cs_bit8, 7'h00, wb_err_cs_bit0 } ; |
`W_ERR_ADDR_ADDR : r_conf_data_out = wb_err_addr ; |
`W_ERR_DATA_ADDR : r_conf_data_out = wb_err_data ; |
|
`CNF_ADDR_ADDR : r_conf_data_out = { 8'h00, cnf_addr_bit23_2, 1'h0, cnf_addr_bit0 } ; |
// `CNF_DATA_ADDR: implemented elsewhere !!! |
// `INT_ACK_ADDR : implemented elsewhere !!! |
`ICR_ADDR : r_conf_data_out = { icr_bit31, 26'h0000_000, icr_bit4_3, icr_bit2_0 } ; |
`ISR_ADDR : r_conf_data_out = { 27'h0000_000, isr_bit4_3, isr_bit2_0 } ; |
|
default : r_conf_data_out = 32'h0000_0000 ; |
endcase |
end |
endcase |
end |
|
`endif |
|
always@(w_conf_address_in or |
status_bit15_11 or status_bit8 or command_bit8 or command_bit6 or command_bit2_0 or |
latency_timer or cache_line_size_reg or |
pci_ba0_bit31_12 or |
pci_img_ctrl0_bit2_1 or pci_am0 or pci_ta0 or pci_ba0_bit0 or |
pci_img_ctrl1_bit2_1 or pci_am1 or pci_ta1 or pci_ba1_bit31_12 or pci_ba1_bit0 or |
pci_img_ctrl2_bit2_1 or pci_am2 or pci_ta2 or pci_ba2_bit31_12 or pci_ba2_bit0 or |
pci_img_ctrl3_bit2_1 or pci_am3 or pci_ta3 or pci_ba3_bit31_12 or pci_ba3_bit0 or |
pci_img_ctrl4_bit2_1 or pci_am4 or pci_ta4 or pci_ba4_bit31_12 or pci_ba4_bit0 or |
pci_img_ctrl5_bit2_1 or pci_am5 or pci_ta5 or pci_ba5_bit31_12 or pci_ba5_bit0 or |
interrupt_line or |
pci_err_cs_bit31_24 or pci_err_cs_bit10 or pci_err_cs_bit9 or pci_err_cs_bit8 or pci_err_cs_bit0 or |
pci_err_addr or pci_err_data or |
wb_ba0_bit31_12 or wb_ba0_bit0 or |
wb_img_ctrl1_bit2_0 or wb_ba1_bit31_12 or wb_ba1_bit0 or wb_am1 or wb_ta1 or |
wb_img_ctrl2_bit2_0 or wb_ba2_bit31_12 or wb_ba2_bit0 or wb_am2 or wb_ta2 or |
wb_img_ctrl3_bit2_0 or wb_ba3_bit31_12 or wb_ba3_bit0 or wb_am3 or wb_ta3 or |
wb_img_ctrl4_bit2_0 or wb_ba4_bit31_12 or wb_ba4_bit0 or wb_am4 or wb_ta4 or |
wb_img_ctrl5_bit2_0 or wb_ba5_bit31_12 or wb_ba5_bit0 or wb_am5 or wb_ta5 or |
wb_err_cs_bit31_24 or /*wb_err_cs_bit10 or*/ wb_err_cs_bit9 or wb_err_cs_bit8 or wb_err_cs_bit0 or |
wb_err_addr or wb_err_data or |
cnf_addr_bit23_2 or cnf_addr_bit0 or icr_bit31 or icr_bit4_3 or icr_bit2_0 or isr_bit4_3 or isr_bit2_0 |
) |
begin |
case (w_conf_address_in[8]) |
1'b0 : |
begin |
case ({w_conf_address_in[7], w_conf_address_in[6]}) |
2'b00 : |
begin |
// PCI header - configuration space |
case (w_conf_address_in[5:2]) |
4'h0: |
begin |
w_conf_data_out = { r_device_id, r_vendor_id } ; |
w_reg_select_dec = 56'h00_0000_0000_0000 ; // Read-Only register |
end |
4'h1: // w_reg_select_dec bit 0 |
begin |
w_conf_data_out = { status_bit15_11, r_status_bit10_9, status_bit8, r_status_bit7, 1'h0, r_status_bit5, |
5'h00, 7'h00, command_bit8, 1'h0, command_bit6, 3'h0, command_bit2_0 } ; |
w_reg_select_dec = 56'h00_0000_0000_0001 ; |
end |
4'h2: |
begin |
w_conf_data_out = { r_class_code, r_revision_id } ; |
w_reg_select_dec = 56'h00_0000_0000_0000 ; // Read-Only register |
end |
4'h3: // w_reg_select_dec bit 1 |
begin |
w_conf_data_out = { 8'h00, r_header_type, latency_timer, cache_line_size_reg } ; |
w_reg_select_dec = 56'h00_0000_0000_0002 ; |
end |
4'h4: // w_reg_select_dec bit 4 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba0_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba0_bit0 & pci_am0[31]; |
w_reg_select_dec = 56'h00_0000_0000_0010 ; // The same for another address |
end |
4'h5: // w_reg_select_dec bit 8 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba1_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba1_bit0 & pci_am1[31]; |
w_reg_select_dec = 56'h00_0000_0000_0100 ; // The same for another address |
end |
4'h6: // w_reg_select_dec bit 12 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba2_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba2_bit0 & pci_am2[31]; |
w_reg_select_dec = 56'h00_0000_0000_1000 ; // The same for another address |
end |
4'h7: // w_reg_select_dec bit 16 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba3_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba3_bit0 & pci_am3[31]; |
w_reg_select_dec = 56'h00_0000_0001_0000 ; // The same for another address |
end |
4'h8: // w_reg_select_dec bit 20 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba4_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba4_bit0 & pci_am4[31]; |
w_reg_select_dec = 56'h00_0000_0010_0000 ; // The same for another address |
end |
4'h9: // w_reg_select_dec bit 24 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba5_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba5_bit0 & pci_am5[31]; |
w_reg_select_dec = 56'h00_0000_0100_0000 ; // The same for another address |
end |
4'hf: // w_reg_select_dec bit 2 |
begin |
w_conf_data_out = { r_max_lat, r_min_gnt, r_interrupt_pin, interrupt_line } ; |
w_reg_select_dec = 56'h00_0000_0000_0004 ; |
end |
default : |
begin |
w_conf_data_out = 32'h0000_0000 ; |
w_reg_select_dec = 56'h00_0000_0000_0000 ; |
end |
endcase |
end |
default : |
begin |
w_conf_data_out = 32'h0000_0000 ; |
w_reg_select_dec = 56'h00_0000_0000_0000 ; |
end |
endcase |
end |
default : |
begin |
// PCI target - configuration space |
case (w_conf_address_in[7:2]) |
`P_IMG_CTRL0_ADDR: // w_reg_select_dec bit 3 |
begin |
w_conf_data_out = { 29'h00000000, pci_img_ctrl0_bit2_1, 1'h0 } ; |
w_reg_select_dec = 56'h00_0000_0000_0008 ; |
end |
`P_BA0_ADDR: // w_reg_select_dec bit 4 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba0_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba0_bit0 & pci_am0[31]; |
w_reg_select_dec = 56'h00_0000_0000_0010 ; // The same for another address |
end |
`P_AM0_ADDR: // w_reg_select_dec bit 5 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0000_0020 ; |
end |
`P_TA0_ADDR: // w_reg_select_dec bit 6 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0000_0040 ; |
end |
`P_IMG_CTRL1_ADDR: // w_reg_select_dec bit 7 |
begin |
w_conf_data_out = { 29'h00000000, pci_img_ctrl1_bit2_1, 1'h0 } ; |
w_reg_select_dec = 56'h00_0000_0000_0080 ; |
end |
`P_BA1_ADDR: // w_reg_select_dec bit 8 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba1_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba1_bit0 & pci_am1[31]; |
w_reg_select_dec = 56'h00_0000_0000_0100 ; // The same for another address |
end |
`P_AM1_ADDR: // w_reg_select_dec bit 9 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0000_0200 ; |
end |
`P_TA1_ADDR: // w_reg_select_dec bit 10 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0000_0400 ; |
end |
`P_IMG_CTRL2_ADDR: // w_reg_select_dec bit 11 |
begin |
w_conf_data_out = { 29'h00000000, pci_img_ctrl2_bit2_1, 1'h0 } ; |
w_reg_select_dec = 56'h00_0000_0000_0800 ; |
end |
`P_BA2_ADDR: // w_reg_select_dec bit 12 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba2_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba2_bit0 & pci_am2[31]; |
w_reg_select_dec = 56'h00_0000_0000_1000 ; // The same for another address |
end |
`P_AM2_ADDR: // w_reg_select_dec bit 13 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0000_2000 ; |
end |
`P_TA2_ADDR: // w_reg_select_dec bit 14 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0000_4000 ; |
end |
`P_IMG_CTRL3_ADDR: // w_reg_select_dec bit 15 |
begin |
w_conf_data_out = { 29'h00000000, pci_img_ctrl3_bit2_1, 1'h0 } ; |
w_reg_select_dec = 56'h00_0000_0000_8000 ; |
end |
`P_BA3_ADDR: // w_reg_select_dec bit 16 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba3_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba3_bit0 & pci_am3[31]; |
w_reg_select_dec = 56'h00_0000_0001_0000 ; // The same for another address |
end |
`P_AM3_ADDR: // w_reg_select_dec bit 17 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0002_0000 ; |
end |
`P_TA3_ADDR: // w_reg_select_dec bit 18 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0004_0000 ; |
end |
`P_IMG_CTRL4_ADDR: // w_reg_select_dec bit 19 |
begin |
w_conf_data_out = { 29'h00000000, pci_img_ctrl4_bit2_1, 1'h0 } ; |
w_reg_select_dec = 56'h00_0000_0008_0000 ; |
end |
`P_BA4_ADDR: // w_reg_select_dec bit 20 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba4_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba4_bit0 & pci_am4[31]; |
w_reg_select_dec = 56'h00_0000_0010_0000 ; // The same for another address |
end |
`P_AM4_ADDR: // w_reg_select_dec bit 21 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0020_0000 ; |
end |
`P_TA4_ADDR: // w_reg_select_dec bit 22 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0040_0000 ; |
end |
`P_IMG_CTRL5_ADDR: // w_reg_select_dec bit 23 |
begin |
w_conf_data_out = { 29'h00000000, pci_img_ctrl5_bit2_1, 1'h0 } ; |
w_reg_select_dec = 56'h00_0000_0080_0000 ; |
end |
`P_BA5_ADDR: // w_reg_select_dec bit 24 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba5_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & |
pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = pci_ba5_bit0 & pci_am5[31]; |
w_reg_select_dec = 56'h00_0000_0100_0000 ; // The same for another address |
end |
`P_AM5_ADDR: // w_reg_select_dec bit 25 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0200_0000 ; |
end |
`P_TA5_ADDR: // w_reg_select_dec bit 26 |
begin |
w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0000_0400_0000 ; |
end |
`P_ERR_CS_ADDR: // w_reg_select_dec bit 27 |
begin |
w_conf_data_out = { pci_err_cs_bit31_24, 13'h0000, pci_err_cs_bit10, pci_err_cs_bit9, |
pci_err_cs_bit8, 7'h00, pci_err_cs_bit0 } ; |
w_reg_select_dec = 56'h00_0000_0800_0000 ; |
end |
`P_ERR_ADDR_ADDR: // w_reg_select_dec bit 28 |
begin |
w_conf_data_out = pci_err_addr ; |
w_reg_select_dec = 56'h00_0000_0000_0000 ; // = 56'h00_0000_1000_0000 ; |
end |
`P_ERR_DATA_ADDR: // w_reg_select_dec bit 29 |
begin |
w_conf_data_out = pci_err_data ; |
w_reg_select_dec = 56'h00_0000_0000_0000 ; // = 56'h00_0000_2000_0000 ; |
end |
// WB slave - configuration space |
`WB_CONF_SPC_BAR_ADDR: |
begin |
w_conf_data_out = { wb_ba0_bit31_12, 11'h000, wb_ba0_bit0 } ; |
w_reg_select_dec = 56'h00_0000_0000_0000 ; // Read-Only register |
end |
`W_IMG_CTRL1_ADDR: // w_reg_select_dec bit 30 |
begin |
w_conf_data_out = { 29'h00000000, wb_img_ctrl1_bit2_0 } ; |
w_reg_select_dec = 56'h00_0000_4000_0000 ; |
end |
`W_BA1_ADDR: // w_reg_select_dec bit 31 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba1_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & |
wb_am1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = wb_ba1_bit0 ; |
w_reg_select_dec = 56'h00_0000_8000_0000 ; |
end |
`W_AM1_ADDR: // w_reg_select_dec bit 32 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0001_0000_0000 ; |
end |
`W_TA1_ADDR: // w_reg_select_dec bit 33 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0002_0000_0000 ; |
end |
`W_IMG_CTRL2_ADDR: // w_reg_select_dec bit 34 |
begin |
w_conf_data_out = { 29'h00000000, wb_img_ctrl2_bit2_0 } ; |
w_reg_select_dec = 56'h00_0004_0000_0000 ; |
end |
`W_BA2_ADDR: // w_reg_select_dec bit 35 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba2_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & |
wb_am2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = wb_ba2_bit0 ; |
w_reg_select_dec = 56'h00_0008_0000_0000 ; |
end |
`W_AM2_ADDR: // w_reg_select_dec bit 36 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0010_0000_0000 ; |
end |
`W_TA2_ADDR: // w_reg_select_dec bit 37 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0020_0000_0000 ; |
end |
`W_IMG_CTRL3_ADDR: // w_reg_select_dec bit 38 |
begin |
w_conf_data_out = { 29'h00000000, wb_img_ctrl3_bit2_0 } ; |
w_reg_select_dec = 56'h00_0040_0000_0000 ; |
end |
`W_BA3_ADDR: // w_reg_select_dec bit 39 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba3_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & |
wb_am3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = wb_ba3_bit0 ; |
w_reg_select_dec = 56'h00_0080_0000_0000 ; |
end |
`W_AM3_ADDR: // w_reg_select_dec bit 40 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0100_0000_0000 ; |
end |
`W_TA3_ADDR: // w_reg_select_dec bit 41 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_0200_0000_0000 ; |
end |
`W_IMG_CTRL4_ADDR: // w_reg_select_dec bit 42 |
begin |
w_conf_data_out = { 29'h00000000, wb_img_ctrl4_bit2_0 } ; |
w_reg_select_dec = 56'h00_0400_0000_0000 ; |
end |
`W_BA4_ADDR: // w_reg_select_dec bit 43 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba4_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & |
wb_am4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = wb_ba4_bit0 ; |
w_reg_select_dec = 56'h00_0800_0000_0000 ; |
end |
`W_AM4_ADDR: // w_reg_select_dec bit 44 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_1000_0000_0000 ; |
end |
`W_TA4_ADDR: // w_reg_select_dec bit 45 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h00_2000_0000_0000 ; |
end |
`W_IMG_CTRL5_ADDR: // w_reg_select_dec bit 46 |
begin |
w_conf_data_out = { 29'h00000000, wb_img_ctrl5_bit2_0 } ; |
w_reg_select_dec = 56'h00_4000_0000_0000 ; |
end |
`W_BA5_ADDR: // w_reg_select_dec bit 47 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba5_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & |
wb_am5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; |
w_conf_data_out[0] = wb_ba5_bit0 ; |
w_reg_select_dec = 56'h00_8000_0000_0000 ; |
end |
`W_AM5_ADDR: // w_reg_select_dec bit 48 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h01_0000_0000_0000 ; |
end |
`W_TA5_ADDR: // w_reg_select_dec bit 49 |
begin |
w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; |
w_reg_select_dec = 56'h02_0000_0000_0000 ; |
end |
`W_ERR_CS_ADDR: // w_reg_select_dec bit 50 |
begin |
w_conf_data_out = { wb_err_cs_bit31_24, /*13*/14'h0000, /*wb_err_cs_bit10,*/ |
wb_err_cs_bit9, wb_err_cs_bit8, 7'h00, wb_err_cs_bit0 } ; |
w_reg_select_dec = 56'h04_0000_0000_0000 ; |
end |
`W_ERR_ADDR_ADDR: // w_reg_select_dec bit 51 |
begin |
w_conf_data_out = wb_err_addr ; |
w_reg_select_dec = 56'h08_0000_0000_0000 ; |
end |
`W_ERR_DATA_ADDR: // w_reg_select_dec bit 52 |
begin |
w_conf_data_out = wb_err_data ; |
w_reg_select_dec = 56'h10_0000_0000_0000 ; |
end |
`CNF_ADDR_ADDR: // w_reg_select_dec bit 53 |
begin |
w_conf_data_out = { 8'h00, cnf_addr_bit23_2, 1'h0, cnf_addr_bit0 } ; |
w_reg_select_dec = 56'h20_0000_0000_0000 ; |
end |
// `CNF_DATA_ADDR: implemented elsewhere !!! |
// `INT_ACK_ADDR: implemented elsewhere !!! |
`ICR_ADDR: // w_reg_select_dec bit 54 |
begin |
w_conf_data_out = { icr_bit31, 26'h0000_000, icr_bit4_3, icr_bit2_0 } ; |
w_reg_select_dec = 56'h40_0000_0000_0000 ; |
end |
`ISR_ADDR: // w_reg_select_dec bit 55 |
begin |
w_conf_data_out = { 27'h0000_000, isr_bit4_3, isr_bit2_0 } ; |
w_reg_select_dec = 56'h80_0000_0000_0000 ; |
end |
default: |
begin |
w_conf_data_out = 32'h0000_0000 ; |
w_reg_select_dec = 56'h00_0000_0000_0000 ; |
end |
endcase |
end |
endcase |
end |
|
// Reduced write data for BASE, MASK and TRANSLATION registers of PCI and WB images |
assign w_conf_pdata_reduced[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = w_conf_data_in[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign w_conf_pdata_reduced[(31-`PCI_NUM_OF_DEC_ADDR_LINES): 0] = 0 ; |
assign w_conf_wdata_reduced[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = w_conf_data_in[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign w_conf_wdata_reduced[(31-`WB_NUM_OF_DEC_ADDR_LINES): 0] = 0 ; |
|
always@(posedge w_clock or posedge reset) |
begin |
// Here are implemented all registers that are reset with RESET signal otherwise they can be normaly written!!! |
// Registers that are commented are implemented after this alwasy statement, because they are e.g. reset with |
// RESET signal, set with some status signal and they are erased with writting '1' into them !!! |
if (reset) |
begin |
/*status_bit15_11 ; status_bit8 ;*/ command_bit8 <= 1'h0 ; command_bit6 <= 1'h0 ; command_bit2_0 <= 3'h0 ; |
latency_timer <= 8'h00 ; cache_line_size_reg <= 8'h00 ; |
// ALL pci_base address registers are the same as pci_baX registers ! |
interrupt_line <= 8'h00 ; |
|
`ifdef HOST |
`ifdef NO_CNF_IMAGE // if PCI bridge is HOST and IMAGE0 is assigned as general image space |
`ifdef PCI_IMAGE0 |
pci_img_ctrl0_bit2_1 <= 2'h0 ; |
pci_ba0_bit31_12 <= 20'h0000_0 ; |
pci_ba0_bit0 <= `PCI_BA0_MEM_IO ; |
pci_am0 <= `PCI_AM0 ; |
pci_ta0 <= 20'h0000_0 ; |
`endif |
`else |
pci_ba0_bit31_12 <= 20'h0000_0 ; |
`endif |
`else // GUEST |
pci_ba0_bit31_12 <= 20'h0000_0 ; |
`endif |
|
pci_img_ctrl1_bit2_1 <= 2'h0 ; |
pci_ba1_bit31_12 <= 20'h0000_0 ; |
`ifdef HOST |
pci_ba1_bit0 <= `PCI_BA1_MEM_IO ; |
`endif |
pci_am1 <= `PCI_AM1; |
pci_ta1 <= 20'h0000_0 ; |
`ifdef PCI_IMAGE2 |
pci_img_ctrl2_bit2_1 <= 2'h0 ; |
pci_ba2_bit31_12 <= 20'h0000_0 ; |
`ifdef HOST |
pci_ba2_bit0 <= `PCI_BA2_MEM_IO ; |
`endif |
pci_am2 <= `PCI_AM2; |
pci_ta2 <= 20'h0000_0 ; |
`endif |
`ifdef PCI_IMAGE3 |
pci_img_ctrl3_bit2_1 <= 2'h0 ; |
pci_ba3_bit31_12 <= 20'h0000_0 ; |
`ifdef HOST |
pci_ba3_bit0 <= `PCI_BA3_MEM_IO ; |
`endif |
pci_am3 <= `PCI_AM3; |
pci_ta3 <= 20'h0000_0 ; |
`endif |
`ifdef PCI_IMAGE4 |
pci_img_ctrl4_bit2_1 <= 2'h0 ; |
pci_ba4_bit31_12 <= 20'h0000_0 ; |
`ifdef HOST |
pci_ba4_bit0 <= `PCI_BA4_MEM_IO ; |
`endif |
pci_am4 <= `PCI_AM4; |
pci_ta4 <= 20'h0000_0 ; |
`endif |
`ifdef PCI_IMAGE5 |
pci_img_ctrl5_bit2_1 <= 2'h0 ; |
pci_ba5_bit31_12 <= 20'h0000_0 ; |
`ifdef HOST |
pci_ba5_bit0 <= `PCI_BA5_MEM_IO ; |
`endif |
pci_am5 <= `PCI_AM5; |
pci_ta5 <= 20'h0000_0 ; |
`endif |
/*pci_err_cs_bit31_24 ; pci_err_cs_bit10; pci_err_cs_bit9 ; pci_err_cs_bit8 ;*/ pci_err_cs_bit0 <= 1'h0 ; |
/*pci_err_addr ;*/ |
/*pci_err_data ;*/ |
// |
wb_img_ctrl1_bit2_0 <= 3'h0 ; |
wb_ba1_bit31_12 <= 20'h0000_0 ; wb_ba1_bit0 <= 1'h0 ; |
wb_am1 <= 20'h0000_0 ; |
wb_ta1 <= 20'h0000_0 ; |
`ifdef WB_IMAGE2 |
wb_img_ctrl2_bit2_0 <= 3'h0 ; |
wb_ba2_bit31_12 <= 20'h0000_0 ; wb_ba2_bit0 <= 1'h0 ; |
wb_am2 <= 20'h0000_0 ; |
wb_ta2 <= 20'h0000_0 ; |
`endif |
`ifdef WB_IMAGE3 |
wb_img_ctrl3_bit2_0 <= 3'h0 ; |
wb_ba3_bit31_12 <= 20'h0000_0 ; wb_ba3_bit0 <= 1'h0 ; |
wb_am3 <= 20'h0000_0 ; |
wb_ta3 <= 20'h0000_0 ; |
`endif |
`ifdef WB_IMAGE4 |
wb_img_ctrl4_bit2_0 <= 3'h0 ; |
wb_ba4_bit31_12 <= 20'h0000_0 ; wb_ba4_bit0 <= 1'h0 ; |
wb_am4 <= 20'h0000_0 ; |
wb_ta4 <= 20'h0000_0 ; |
`endif |
`ifdef WB_IMAGE5 |
wb_img_ctrl5_bit2_0 <= 3'h0 ; |
wb_ba5_bit31_12 <= 20'h0000_0 ; wb_ba5_bit0 <= 1'h0 ; |
wb_am5 <= 20'h0000_0 ; |
wb_ta5 <= 20'h0000_0 ; |
`endif |
/*wb_err_cs_bit31_24 ; wb_err_cs_bit10 ; wb_err_cs_bit9 ; wb_err_cs_bit8 ;*/ wb_err_cs_bit0 <= 1'h0 ; |
/*wb_err_addr ;*/ |
/*wb_err_data ;*/ |
|
`ifdef HOST |
cnf_addr_bit23_2 <= 22'h0000_00 ; cnf_addr_bit0 <= 1'h0 ; |
`endif |
|
icr_bit31 <= 1'h0 ; |
`ifdef HOST |
icr_bit2_0 <= 3'h0 ; |
icr_bit4_3 <= 2'h0 ; |
`else |
icr_bit2_0[2:0] <= 3'h0 ; |
`endif |
/*isr_bit4_3 ; isr_bit2_0 ;*/ |
end |
/* ----------------------------------------------------------------------------------------------------------- |
Following register bits should have asynchronous RESET & SET! That is why they are IMPLEMENTED separately |
after this ALWAYS block!!! (for every register bit, there are two D-FF implemented) |
status_bit15_11[15] <= 1'b1 ; |
status_bit15_11[14] <= 1'b1 ; |
status_bit15_11[13] <= 1'b1 ; |
status_bit15_11[12] <= 1'b1 ; |
status_bit15_11[11] <= 1'b1 ; |
status_bit8 <= 1'b1 ; |
pci_err_cs_bit10 <= 1'b1 ; |
pci_err_cs_bit9 <= 1'b1 ; |
pci_err_cs_bit8 <= 1'b1 ; |
pci_err_cs_bit31_24 <= { pci_error_be, pci_error_bc } ; |
pci_err_addr <= pci_error_addr ; |
pci_err_data <= pci_error_data ; |
wb_err_cs_bit10 <= 1'b1 ; |
wb_err_cs_bit9 <= 1'b1 ; |
wb_err_cs_bit8 <= 1'b1 ; |
wb_err_cs_bit31_24 <= { wb_error_be, wb_error_bc } ; |
wb_err_addr <= wb_error_addr ; |
wb_err_data <= wb_error_data ; |
isr_bit4_0[4] <= 1'b1 & icr_bit4_0[4] ; |
isr_bit4_0[3] <= 1'b1 & icr_bit4_0[3] ; |
isr_bit4_0[2] <= 1'b1 & icr_bit4_0[2] ; |
isr_bit4_0[1] <= 1'b1 & icr_bit4_0[1] ; |
isr_bit4_0[0] <= 1'b1 & icr_bit4_0[0] ; |
-----------------------------------------------------------------------------------------------------------*/ |
// Here follows normal writting to registers (only to their valid bits) ! |
else |
begin |
if (w_we) |
begin |
// PCI header - configuration space |
if (w_reg_select_dec[0]) // w_conf_address_in[5:2] = 4'h1: |
begin |
if (~w_byte_en[1]) |
command_bit8 <= w_conf_data_in[8] ; |
if (~w_byte_en[0]) |
begin |
command_bit6 <= w_conf_data_in[6] ; |
command_bit2_0 <= w_conf_data_in[2:0] ; |
end |
end |
if (w_reg_select_dec[1]) // w_conf_address_in[5:2] = 4'h3: |
begin |
if (~w_byte_en[1]) |
latency_timer <= w_conf_data_in[15:8] ; |
if (~w_byte_en[0]) |
cache_line_size_reg <= w_conf_data_in[7:0] ; |
end |
// if (w_reg_select_dec[4]) // w_conf_address_in[5:2] = 4'h4: |
// Also used with IMAGE0 |
|
// if (w_reg_select_dec[8]) // w_conf_address_in[5:2] = 4'h5: |
// Also used with IMAGE1 |
|
// if (w_reg_select_dec[12]) // w_conf_address_in[5:2] = 4'h6: |
// Also used with IMAGE2 |
|
// if (w_reg_select_dec[16]) // w_conf_address_in[5:2] = 4'h7: |
// Also used with IMAGE3 |
|
// if (w_reg_select_dec[20]) // w_conf_address_in[5:2] = 4'h8: |
// Also used with IMAGE4 |
|
// if (w_reg_select_dec[24]) // w_conf_address_in[5:2] = 4'h9: |
// Also used with IMAGE5 and IMAGE6 |
if (w_reg_select_dec[2]) // w_conf_address_in[5:2] = 4'hf: |
begin |
if (~w_byte_en[0]) |
interrupt_line <= w_conf_data_in[7:0] ; |
end |
// PCI target - configuration space |
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
`ifdef PCI_IMAGE0 // if PCI bridge is HOST and IMAGE0 is assigned as general image space |
if (w_reg_select_dec[3]) // case (w_conf_address_in[7:2]) = `P_IMG_CTRL0_ADDR: |
begin |
if (~w_byte_en[0]) |
pci_img_ctrl0_bit2_1 <= w_conf_data_in[2:1] ; |
end |
if (w_reg_select_dec[4]) // case (w_conf_address_in[7:2]) = `P_BA0_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ba0_bit31_12[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ba0_bit31_12[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ba0_bit31_12[15:12] <= w_conf_pdata_reduced[15:12] ; |
if (~w_byte_en[0]) |
pci_ba0_bit0 <= w_conf_data_in[0] ; |
end |
if (w_reg_select_dec[5]) // case (w_conf_address_in[7:2]) = `P_AM0_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_am0[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_am0[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_am0[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
if (w_reg_select_dec[6]) // case (w_conf_address_in[7:2]) = `P_TA0_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ta0[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ta0[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ta0[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
`endif |
`else |
if (w_reg_select_dec[4]) // case (w_conf_address_in[7:2]) = `P_BA0_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ba0_bit31_12[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ba0_bit31_12[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ba0_bit31_12[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
`endif |
`else // GUEST |
if (w_reg_select_dec[4]) // case (w_conf_address_in[7:2]) = `P_BA0_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ba0_bit31_12[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ba0_bit31_12[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ba0_bit31_12[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
`endif |
if (w_reg_select_dec[7]) // case (w_conf_address_in[7:2]) = `P_IMG_CTRL1_ADDR: |
begin |
if (~w_byte_en[0]) |
pci_img_ctrl1_bit2_1 <= w_conf_data_in[2:1] ; |
end |
if (w_reg_select_dec[8]) // case (w_conf_address_in[7:2]) = `P_BA1_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ba1_bit31_12[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ba1_bit31_12[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ba1_bit31_12[15:12] <= w_conf_pdata_reduced[15:12] ; |
`ifdef HOST |
if (~w_byte_en[0]) |
pci_ba1_bit0 <= w_conf_data_in[0] ; |
`endif |
end |
if (w_reg_select_dec[9]) // case (w_conf_address_in[7:2]) = `P_AM1_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_am1[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_am1[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_am1[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
if (w_reg_select_dec[10]) // case (w_conf_address_in[7:2]) = `P_TA1_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ta1[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ta1[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ta1[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
`ifdef PCI_IMAGE2 |
if (w_reg_select_dec[11]) // case (w_conf_address_in[7:2]) = `P_IMG_CTRL2_ADDR: |
begin |
if (~w_byte_en[0]) |
pci_img_ctrl2_bit2_1 <= w_conf_data_in[2:1] ; |
end |
if (w_reg_select_dec[12]) // case (w_conf_address_in[7:2]) = `P_BA2_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ba2_bit31_12[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ba2_bit31_12[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ba2_bit31_12[15:12] <= w_conf_pdata_reduced[15:12] ; |
`ifdef HOST |
if (~w_byte_en[0]) |
pci_ba2_bit0 <= w_conf_data_in[0] ; |
`endif |
end |
if (w_reg_select_dec[13]) // case (w_conf_address_in[7:2]) = `P_AM2_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_am2[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_am2[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_am2[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
if (w_reg_select_dec[14]) // case (w_conf_address_in[7:2]) = `P_TA2_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ta2[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ta2[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ta2[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
`endif |
`ifdef PCI_IMAGE3 |
if (w_reg_select_dec[15]) // case (w_conf_address_in[7:2]) = `P_IMG_CTRL3_ADDR: |
begin |
if (~w_byte_en[0]) |
pci_img_ctrl3_bit2_1 <= w_conf_data_in[2:1] ; |
end |
if (w_reg_select_dec[16]) // case (w_conf_address_in[7:2]) = `P_BA3_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ba3_bit31_12[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ba3_bit31_12[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ba3_bit31_12[15:12] <= w_conf_pdata_reduced[15:12] ; |
`ifdef HOST |
if (~w_byte_en[0]) |
pci_ba3_bit0 <= w_conf_data_in[0] ; |
`endif |
end |
if (w_reg_select_dec[17]) // case (w_conf_address_in[7:2]) = `P_AM3_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_am3[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_am3[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_am3[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
if (w_reg_select_dec[18]) // case (w_conf_address_in[7:2]) = `P_TA3_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ta3[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ta3[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ta3[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
`endif |
`ifdef PCI_IMAGE4 |
if (w_reg_select_dec[19]) // case (w_conf_address_in[7:2]) = `P_IMG_CTRL4_ADDR: |
begin |
if (~w_byte_en[0]) |
pci_img_ctrl4_bit2_1 <= w_conf_data_in[2:1] ; |
end |
if (w_reg_select_dec[20]) // case (w_conf_address_in[7:2]) = `P_BA4_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ba4_bit31_12[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ba4_bit31_12[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ba4_bit31_12[15:12] <= w_conf_pdata_reduced[15:12] ; |
`ifdef HOST |
if (~w_byte_en[0]) |
pci_ba4_bit0 <= w_conf_data_in[0] ; |
`endif |
end |
if (w_reg_select_dec[21]) // case (w_conf_address_in[7:2]) = `P_AM4_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_am4[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_am4[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_am4[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
if (w_reg_select_dec[22]) // case (w_conf_address_in[7:2]) = `P_TA4_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ta4[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ta4[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ta4[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
`endif |
`ifdef PCI_IMAGE5 |
if (w_reg_select_dec[23]) // case (w_conf_address_in[7:2]) = `P_IMG_CTRL5_ADDR: |
begin |
if (~w_byte_en[0]) |
pci_img_ctrl5_bit2_1 <= w_conf_data_in[2:1] ; |
end |
if (w_reg_select_dec[24]) // case (w_conf_address_in[7:2]) = `P_BA5_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ba5_bit31_12[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ba5_bit31_12[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ba5_bit31_12[15:12] <= w_conf_pdata_reduced[15:12] ; |
`ifdef HOST |
if (~w_byte_en[0]) |
pci_ba5_bit0 <= w_conf_data_in[0] ; |
`endif |
end |
if (w_reg_select_dec[25]) // case (w_conf_address_in[7:2]) = `P_AM5_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_am5[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_am5[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_am5[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
if (w_reg_select_dec[26]) // case (w_conf_address_in[7:2]) = `P_TA5_ADDR: |
begin |
if (~w_byte_en[3]) |
pci_ta5[31:24] <= w_conf_pdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
pci_ta5[23:16] <= w_conf_pdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
pci_ta5[15:12] <= w_conf_pdata_reduced[15:12] ; |
end |
`endif |
if (w_reg_select_dec[27]) // case (w_conf_address_in[7:2]) = `P_ERR_CS_ADDR: |
begin |
if (~w_byte_en[0]) |
pci_err_cs_bit0 <= w_conf_data_in[0] ; |
end |
// WB slave - configuration space |
if (w_reg_select_dec[30]) // case (w_conf_address_in[7:2]) = `W_IMG_CTRL1_ADDR: |
begin |
if (~w_byte_en[0]) |
wb_img_ctrl1_bit2_0 <= w_conf_data_in[2:0] ; |
end |
if (w_reg_select_dec[31]) // case (w_conf_address_in[7:2]) = `W_BA1_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_ba1_bit31_12[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_ba1_bit31_12[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_ba1_bit31_12[15:12] <= w_conf_wdata_reduced[15:12] ; |
if (~w_byte_en[0]) |
wb_ba1_bit0 <= w_conf_data_in[0] ; |
end |
if (w_reg_select_dec[32]) // case (w_conf_address_in[7:2]) = `W_AM1_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_am1[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_am1[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_am1[15:12] <= w_conf_wdata_reduced[15:12] ; |
end |
if (w_reg_select_dec[33]) // case (w_conf_address_in[7:2]) = `W_TA1_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_ta1[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_ta1[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_ta1[15:12] <= w_conf_wdata_reduced[15:12] ; |
end |
`ifdef WB_IMAGE2 |
if (w_reg_select_dec[34]) // case (w_conf_address_in[7:2]) = `W_IMG_CTRL2_ADDR: |
begin |
if (~w_byte_en[0]) |
wb_img_ctrl2_bit2_0 <= w_conf_data_in[2:0] ; |
end |
if (w_reg_select_dec[35]) // case (w_conf_address_in[7:2]) = `W_BA2_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_ba2_bit31_12[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_ba2_bit31_12[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_ba2_bit31_12[15:12] <= w_conf_wdata_reduced[15:12] ; |
if (~w_byte_en[0]) |
wb_ba2_bit0 <= w_conf_data_in[0] ; |
end |
if (w_reg_select_dec[36]) // case (w_conf_address_in[7:2]) = `W_AM2_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_am2[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_am2[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_am2[15:12] <= w_conf_wdata_reduced[15:12] ; |
end |
if (w_reg_select_dec[37]) // case (w_conf_address_in[7:2]) = `W_TA2_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_ta2[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_ta2[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_ta2[15:12] <= w_conf_wdata_reduced[15:12] ; |
end |
`endif |
`ifdef WB_IMAGE3 |
if (w_reg_select_dec[38]) // case (w_conf_address_in[7:2]) = `W_IMG_CTRL3_ADDR: |
begin |
if (~w_byte_en[0]) |
wb_img_ctrl3_bit2_0 <= w_conf_data_in[2:0] ; |
end |
if (w_reg_select_dec[39]) // case (w_conf_address_in[7:2]) = `W_BA3_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_ba3_bit31_12[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_ba3_bit31_12[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_ba3_bit31_12[15:12] <= w_conf_wdata_reduced[15:12] ; |
if (~w_byte_en[0]) |
wb_ba3_bit0 <= w_conf_data_in[0] ; |
end |
if (w_reg_select_dec[40]) // case (w_conf_address_in[7:2]) = `W_AM3_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_am3[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_am3[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_am3[15:12] <= w_conf_wdata_reduced[15:12] ; |
end |
if (w_reg_select_dec[41]) // case (w_conf_address_in[7:2]) = `W_TA3_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_ta3[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_ta3[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_ta3[15:12] <= w_conf_wdata_reduced[15:12] ; |
end |
`endif |
`ifdef WB_IMAGE4 |
if (w_reg_select_dec[42]) // case (w_conf_address_in[7:2]) = `W_IMG_CTRL4_ADDR: |
begin |
if (~w_byte_en[0]) |
wb_img_ctrl4_bit2_0 <= w_conf_data_in[2:0] ; |
end |
if (w_reg_select_dec[43]) // case (w_conf_address_in[7:2]) = `W_BA4_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_ba4_bit31_12[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_ba4_bit31_12[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_ba4_bit31_12[15:12] <= w_conf_wdata_reduced[15:12] ; |
if (~w_byte_en[0]) |
wb_ba4_bit0 <= w_conf_data_in[0] ; |
end |
if (w_reg_select_dec[44]) // case (w_conf_address_in[7:2]) = `W_AM4_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_am4[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_am4[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_am4[15:12] <= w_conf_wdata_reduced[15:12] ; |
end |
if (w_reg_select_dec[45]) // case (w_conf_address_in[7:2]) = `W_TA4_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_ta4[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_ta4[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_ta4[15:12] <= w_conf_wdata_reduced[15:12] ; |
end |
`endif |
`ifdef WB_IMAGE5 |
if (w_reg_select_dec[46]) // case (w_conf_address_in[7:2]) = `W_IMG_CTRL5_ADDR: |
begin |
if (~w_byte_en[0]) |
wb_img_ctrl5_bit2_0 <= w_conf_data_in[2:0] ; |
end |
if (w_reg_select_dec[47]) // case (w_conf_address_in[7:2]) = `W_BA5_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_ba5_bit31_12[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_ba5_bit31_12[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_ba5_bit31_12[15:12] <= w_conf_wdata_reduced[15:12] ; |
if (~w_byte_en[0]) |
wb_ba5_bit0 <= w_conf_data_in[0] ; |
end |
if (w_reg_select_dec[48]) // case (w_conf_address_in[7:2]) = `W_AM5_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_am5[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_am5[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_am5[15:12] <= w_conf_wdata_reduced[15:12] ; |
end |
if (w_reg_select_dec[49]) // case (w_conf_address_in[7:2]) = `W_TA5_ADDR: |
begin |
if (~w_byte_en[3]) |
wb_ta5[31:24] <= w_conf_wdata_reduced[31:24] ; |
if (~w_byte_en[2]) |
wb_ta5[23:16] <= w_conf_wdata_reduced[23:16] ; |
if (~w_byte_en[1]) |
wb_ta5[15:12] <= w_conf_wdata_reduced[15:12] ; |
end |
`endif |
if (w_reg_select_dec[50]) // case (w_conf_address_in[7:2]) = `W_ERR_CS_ADDR: |
begin |
if (~w_byte_en[0]) |
wb_err_cs_bit0 <= w_conf_data_in[0] ; |
end |
|
`ifdef HOST |
if (w_reg_select_dec[53]) // case (w_conf_address_in[7:2]) = `CNF_ADDR_ADDR: |
begin |
if (~w_byte_en[2]) |
cnf_addr_bit23_2[23:16] <= w_conf_data_in[23:16] ; |
if (~w_byte_en[1]) |
cnf_addr_bit23_2[15:8] <= w_conf_data_in[15:8] ; |
if (~w_byte_en[0]) |
begin |
cnf_addr_bit23_2[7:2] <= w_conf_data_in[7:2] ; |
cnf_addr_bit0 <= w_conf_data_in[0] ; |
end |
end |
`endif |
// `CNF_DATA_ADDR: implemented elsewhere !!! |
// `INT_ACK_ADDR : implemented elsewhere !!! |
if (w_reg_select_dec[54]) // case (w_conf_address_in[7:2]) = `ICR_ADDR: |
begin |
if (~w_byte_en[3]) |
icr_bit31 <= w_conf_data_in[31] ; |
if (~w_byte_en[0]) |
`ifdef HOST |
icr_bit4_3 <= w_conf_data_in[4:3] ; |
icr_bit2_0 <= w_conf_data_in[2:0] ; |
`else |
icr_bit2_0[2:0] <= w_conf_data_in[2:0] ; |
`endif |
end |
end |
end |
end |
|
// This signals are synchronous resets for registers, whic occures when asynchronous RESET is '1' or |
// data '1' is synchronously written into them! |
reg delete_status_bit15 ; |
reg delete_status_bit14 ; |
reg delete_status_bit13 ; |
reg delete_status_bit12 ; |
reg delete_status_bit11 ; |
reg delete_status_bit8 ; |
reg delete_pci_err_cs_bit8 ; |
reg delete_wb_err_cs_bit8 ; |
reg delete_isr_bit4 ; |
reg delete_isr_bit3 ; |
reg delete_isr_bit2 ; |
reg delete_isr_bit1 ; |
|
// This are aditional register bits, which are resets when their value is '1' !!! |
always@(w_we or w_reg_select_dec or w_conf_data_in or w_byte_en) |
begin |
// If '1' is written into, then it also sets signals to '1' |
case ({w_we, w_reg_select_dec[0], w_reg_select_dec[27], w_reg_select_dec[50], w_reg_select_dec[55]}) |
{1'b1, 4'b1000} : |
begin |
delete_status_bit15 <= w_conf_data_in[31] & !w_byte_en[3] ; |
delete_status_bit14 <= w_conf_data_in[30] & !w_byte_en[3] ; |
delete_status_bit13 <= w_conf_data_in[29] & !w_byte_en[3] ; |
delete_status_bit12 <= w_conf_data_in[28] & !w_byte_en[3] ; |
delete_status_bit11 <= w_conf_data_in[27] & !w_byte_en[3] ; |
delete_status_bit8 <= w_conf_data_in[24] & !w_byte_en[3] ; |
delete_pci_err_cs_bit8 <= 1'b0 ; |
delete_wb_err_cs_bit8 <= 1'b0 ; |
delete_isr_bit4 <= 1'b0 ; |
delete_isr_bit3 <= 1'b0 ; |
delete_isr_bit2 <= 1'b0 ; |
delete_isr_bit1 <= 1'b0 ; |
end |
{1'b1, 4'b0100} : |
begin |
delete_status_bit15 <= 1'b0 ; |
delete_status_bit14 <= 1'b0 ; |
delete_status_bit13 <= 1'b0 ; |
delete_status_bit12 <= 1'b0 ; |
delete_status_bit11 <= 1'b0 ; |
delete_status_bit8 <= 1'b0 ; |
delete_pci_err_cs_bit8 <= w_conf_data_in[8] & !w_byte_en[1] ; |
delete_wb_err_cs_bit8 <= 1'b0 ; |
delete_isr_bit4 <= 1'b0 ; |
delete_isr_bit3 <= 1'b0 ; |
delete_isr_bit2 <= 1'b0 ; |
delete_isr_bit1 <= 1'b0 ; |
end |
{1'b1, 4'b0010} : |
begin |
delete_status_bit15 <= 1'b0 ; |
delete_status_bit14 <= 1'b0 ; |
delete_status_bit13 <= 1'b0 ; |
delete_status_bit12 <= 1'b0 ; |
delete_status_bit11 <= 1'b0 ; |
delete_status_bit8 <= 1'b0 ; |
delete_pci_err_cs_bit8 <= 1'b0 ; |
delete_wb_err_cs_bit8 <= w_conf_data_in[8] & !w_byte_en[1] ; |
delete_isr_bit4 <= 1'b0 ; |
delete_isr_bit3 <= 1'b0 ; |
delete_isr_bit2 <= 1'b0 ; |
delete_isr_bit1 <= 1'b0 ; |
end |
{1'b1, 4'b0001} : |
begin |
delete_status_bit15 <= 1'b0 ; |
delete_status_bit14 <= 1'b0 ; |
delete_status_bit13 <= 1'b0 ; |
delete_status_bit12 <= 1'b0 ; |
delete_status_bit11 <= 1'b0 ; |
delete_status_bit8 <= 1'b0 ; |
delete_pci_err_cs_bit8 <= 1'b0 ; |
delete_wb_err_cs_bit8 <= 1'b0 ; |
delete_isr_bit4 <= w_conf_data_in[4] & !w_byte_en[0] ; |
delete_isr_bit3 <= w_conf_data_in[3] & !w_byte_en[0] ; |
delete_isr_bit2 <= w_conf_data_in[2] & !w_byte_en[0] ; |
delete_isr_bit1 <= w_conf_data_in[1] & !w_byte_en[0] ; |
end |
default : |
begin |
delete_status_bit15 <= 1'b0 ; |
delete_status_bit14 <= 1'b0 ; |
delete_status_bit13 <= 1'b0 ; |
delete_status_bit12 <= 1'b0 ; |
delete_status_bit11 <= 1'b0 ; |
delete_status_bit8 <= 1'b0 ; |
delete_pci_err_cs_bit8 <= 1'b0 ; |
delete_wb_err_cs_bit8 <= 1'b0 ; |
delete_isr_bit4 <= 1'b0 ; |
delete_isr_bit3 <= 1'b0 ; |
delete_isr_bit2 <= 1'b0 ; |
delete_isr_bit1 <= 1'b0 ; |
end |
endcase |
end |
|
// STATUS BITS of PCI Header status register |
`ifdef SYNCHRONEOUS_CLOCK_DOMAINS |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit15_11[15] <= 1'b0 ; |
else |
begin |
if (perr_in) // Synchronous set |
status_bit15_11[15] <= 1'b1 ; |
else if (delete_status_bit15) // Synchronous reset |
status_bit15_11[15] <= 1'b0 ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit15_11[14] <= 1'b0 ; |
else |
begin |
if (serr_in) // Synchronous set |
status_bit15_11[14] <= 1'b1 ; |
else if (delete_status_bit14) // Synchronous reset |
status_bit15_11[14] <= 1'b0 ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit15_11[13] <= 1'b0 ; |
else |
begin |
if (master_abort_recv) // Synchronous set |
status_bit15_11[13] <= 1'b1 ; |
else if (delete_status_bit13) // Synchronous reset |
status_bit15_11[13] <= 1'b0 ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit15_11[12] <= 1'b0 ; |
else |
begin |
if (target_abort_recv) // Synchronous set |
status_bit15_11[12] <= 1'b1 ; |
else if (delete_status_bit12) // Synchronous reset |
status_bit15_11[12] <= 1'b0 ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit15_11[11] <= 1'b0 ; |
else |
begin |
if (target_abort_set) // Synchronous set |
status_bit15_11[11] <= 1'b1 ; |
else if (delete_status_bit11) // Synchronous reset |
status_bit15_11[11] <= 1'b0 ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit8 <= 1'b0 ; |
else |
begin |
if (master_data_par_err) // Synchronous set |
status_bit8 <= 1'b1 ; |
else if (delete_status_bit8) // Synchronous reset |
status_bit8 <= 1'b0 ; |
end |
end |
`else // not SYNCHRONEOUS_CLOCK_DOMAINS |
`ifdef HOST |
reg [15:11] set_status_bit15_11; |
reg set_status_bit8; |
wire delete_set_status_bit15; |
wire delete_set_status_bit14; |
wire delete_set_status_bit13; |
wire delete_set_status_bit12; |
wire delete_set_status_bit11; |
wire delete_set_status_bit8; |
wire block_set_status_bit15; |
wire block_set_status_bit14; |
wire block_set_status_bit13; |
wire block_set_status_bit12; |
wire block_set_status_bit11; |
wire block_set_status_bit8; |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_status_15 |
( |
.set_clk_in (pci_clk), |
.delete_clk_in (wb_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_status_bit15), |
.block_set_out (block_set_status_bit15), |
.delete_in (delete_status_bit15) |
); |
// Setting FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_status_bit15_11[15] <= 1'b0 ; |
else |
begin |
if (perr_in) // Synchronous set |
set_status_bit15_11[15] <= 1'b1 ; |
else if (delete_set_status_bit15) // Synchronous reset |
set_status_bit15_11[15] <= 1'b0 ; |
end |
end |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_status_14 |
( |
.set_clk_in (pci_clk), |
.delete_clk_in (wb_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_status_bit14), |
.block_set_out (block_set_status_bit14), |
.delete_in (delete_status_bit14) |
); |
// Setting FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_status_bit15_11[14] <= 1'b0 ; |
else |
begin |
if (serr_in) // Synchronous set |
set_status_bit15_11[14] <= 1'b1 ; |
else if (delete_set_status_bit14) // Synchronous reset |
set_status_bit15_11[14] <= 1'b0 ; |
end |
end |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_status_13 |
( |
.set_clk_in (pci_clk), |
.delete_clk_in (wb_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_status_bit13), |
.block_set_out (block_set_status_bit13), |
.delete_in (delete_status_bit13) |
); |
// Setting FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_status_bit15_11[13] <= 1'b0 ; |
else |
begin |
if (master_abort_recv) // Synchronous set |
set_status_bit15_11[13] <= 1'b1 ; |
else if (delete_set_status_bit13) // Synchronous reset |
set_status_bit15_11[13] <= 1'b0 ; |
end |
end |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_status_12 |
( |
.set_clk_in (pci_clk), |
.delete_clk_in (wb_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_status_bit12), |
.block_set_out (block_set_status_bit12), |
.delete_in (delete_status_bit12) |
); |
// Setting FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_status_bit15_11[12] <= 1'b0 ; |
else |
begin |
if (target_abort_recv) // Synchronous set |
set_status_bit15_11[12] <= 1'b1 ; |
else if (delete_set_status_bit12) // Synchronous reset |
set_status_bit15_11[12] <= 1'b0 ; |
end |
end |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_status_11 |
( |
.set_clk_in (pci_clk), |
.delete_clk_in (wb_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_status_bit11), |
.block_set_out (block_set_status_bit11), |
.delete_in (delete_status_bit11) |
); |
// Setting FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_status_bit15_11[11] <= 1'b0 ; |
else |
begin |
if (target_abort_set) // Synchronous set |
set_status_bit15_11[11] <= 1'b1 ; |
else if (delete_set_status_bit11) // Synchronous reset |
set_status_bit15_11[11] <= 1'b0 ; |
end |
end |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_status_8 |
( |
.set_clk_in (pci_clk), |
.delete_clk_in (wb_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_status_bit8), |
.block_set_out (block_set_status_bit8), |
.delete_in (delete_status_bit8) |
); |
// Setting FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_status_bit8 <= 1'b0 ; |
else |
begin |
if (master_data_par_err) // Synchronous set |
set_status_bit8 <= 1'b1 ; |
else if (delete_set_status_bit8) // Synchronous reset |
set_status_bit8 <= 1'b0 ; |
end |
end |
wire [5:0] status_bits = {set_status_bit15_11[15] && !block_set_status_bit15, |
set_status_bit15_11[14] && !block_set_status_bit14, |
set_status_bit15_11[13] && !block_set_status_bit13, |
set_status_bit15_11[12] && !block_set_status_bit12, |
set_status_bit15_11[11] && !block_set_status_bit11, |
set_status_bit8 && !block_set_status_bit8 } ; |
wire [5:0] meta_status_bits ; |
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(6, 0) status_bits_sync |
( |
.data_in (status_bits), |
.clk_out (wb_clk), |
.sync_data_out (meta_status_bits), |
.async_reset (reset) |
) ; |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) |
begin |
status_bit15_11[15:11] <= 5'b0 ; |
status_bit8 <= 1'b0 ; |
end |
else |
begin |
status_bit15_11[15:11] <= meta_status_bits[5:1] ; |
status_bit8 <= meta_status_bits[0] ; |
end |
end |
`else // GUEST |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit15_11[15] <= 1'b0 ; |
else |
begin |
if (perr_in) // Synchronous set |
status_bit15_11[15] <= 1'b1 ; |
else if (delete_status_bit15) // Synchronous reset |
status_bit15_11[15] <= 1'b0 ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit15_11[14] <= 1'b0 ; |
else |
begin |
if (serr_in) // Synchronous set |
status_bit15_11[14] <= 1'b1 ; |
else if (delete_status_bit14) // Synchronous reset |
status_bit15_11[14] <= 1'b0 ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit15_11[13] <= 1'b0 ; |
else |
begin |
if (master_abort_recv) // Synchronous set |
status_bit15_11[13] <= 1'b1 ; |
else if (delete_status_bit13) // Synchronous reset |
status_bit15_11[13] <= 1'b0 ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit15_11[12] <= 1'b0 ; |
else |
begin |
if (target_abort_recv) // Synchronous set |
status_bit15_11[12] <= 1'b1 ; |
else if (delete_status_bit12) // Synchronous reset |
status_bit15_11[12] <= 1'b0 ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit15_11[11] <= 1'b0 ; |
else |
begin |
if (target_abort_set) // Synchronous set |
status_bit15_11[11] <= 1'b1 ; |
else if (delete_status_bit11) // Synchronous reset |
status_bit15_11[11] <= 1'b0 ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
status_bit8 <= 1'b0 ; |
else |
begin |
if (master_data_par_err) // Synchronous set |
status_bit8 <= 1'b1 ; |
else if (delete_status_bit8) // Synchronous reset |
status_bit8 <= 1'b0 ; |
end |
end |
`endif |
`endif |
|
// STATUS BITS of P_ERR_CS - PCI error control and status register |
`ifdef SYNCHRONEOUS_CLOCK_DOMAINS |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
pci_err_cs_bit8 <= 1'b0 ; |
else |
begin |
if (pci_error_sig && pci_err_cs_bit0) // Synchronous set |
pci_err_cs_bit8 <= 1'b1 ; |
else if (delete_pci_err_cs_bit8) // Synchronous reset |
pci_err_cs_bit8 <= 1'b0 ; |
end |
end |
`else // not SYNCHRONEOUS_CLOCK_DOMAINS |
`ifdef HOST |
// Set and clear FF |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
pci_err_cs_bit8 <= 1'b0 ; |
else |
begin |
if (pci_error_sig && pci_err_cs_bit0) // Synchronous set |
pci_err_cs_bit8 <= 1'b1 ; |
else if (delete_pci_err_cs_bit8) // Synchronous reset |
pci_err_cs_bit8 <= 1'b0 ; |
end |
end |
`else // GUEST |
reg set_pci_err_cs_bit8; |
wire delete_set_pci_err_cs_bit8; |
wire block_set_pci_err_cs_bit8; |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_pci_err_cs_8 |
( |
.set_clk_in (wb_clk), |
.delete_clk_in (pci_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_pci_err_cs_bit8), |
.block_set_out (block_set_pci_err_cs_bit8), |
.delete_in (delete_pci_err_cs_bit8) |
); |
// Setting FF |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_pci_err_cs_bit8 <= 1'b0 ; |
else |
begin |
if (pci_error_sig && pci_err_cs_bit0) // Synchronous set |
set_pci_err_cs_bit8 <= 1'b1 ; |
else if (delete_set_pci_err_cs_bit8) // Synchronous reset |
set_pci_err_cs_bit8 <= 1'b0 ; |
end |
end |
wire pci_err_cs_bits = set_pci_err_cs_bit8 && !block_set_pci_err_cs_bit8 ; |
wire meta_pci_err_cs_bits ; |
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(1,0) pci_err_cs_bits_sync |
( |
.data_in (pci_err_cs_bits), |
.clk_out (pci_clk), |
.sync_data_out (meta_pci_err_cs_bits), |
.async_reset (reset) |
) ; |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) |
pci_err_cs_bit8 <= 1'b0 ; |
else |
pci_err_cs_bit8 <= meta_pci_err_cs_bits ; |
end |
`endif |
`endif |
// Set and clear FF |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
pci_err_cs_bit10 <= 1'b0 ; |
else |
begin |
if (pci_error_sig) // Synchronous report |
pci_err_cs_bit10 <= pci_error_rty_exp ; |
end |
end |
// Set and clear FF |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
pci_err_cs_bit9 <= 1'b0 ; |
else |
begin |
if (pci_error_sig) // Synchronous report |
pci_err_cs_bit9 <= pci_error_es ; |
end |
end |
// Set and clear FF |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
begin |
pci_err_cs_bit31_24 <= 8'h00 ; |
pci_err_addr <= 32'h0000_0000 ; |
pci_err_data <= 32'h0000_0000 ; |
end |
else |
if (pci_error_sig) // Synchronous report |
begin |
pci_err_cs_bit31_24 <= { pci_error_be, pci_error_bc } ; |
pci_err_addr <= pci_error_addr ; |
pci_err_data <= pci_error_data ; |
end |
end |
|
// STATUS BITS of W_ERR_CS - WB error control and status register |
`ifdef SYNCHRONEOUS_CLOCK_DOMAINS |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
wb_err_cs_bit8 <= 1'b0 ; |
else |
begin |
if (wb_error_sig && wb_err_cs_bit0) // Synchronous set |
wb_err_cs_bit8 <= 1'b1 ; |
else if (delete_wb_err_cs_bit8) // Synchronous reset |
wb_err_cs_bit8 <= 1'b0 ; |
end |
end |
`else // not SYNCHRONEOUS_CLOCK_DOMAINS |
`ifdef HOST |
reg set_wb_err_cs_bit8; |
wire delete_set_wb_err_cs_bit8; |
wire block_set_wb_err_cs_bit8; |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_wb_err_cs_8 |
( |
.set_clk_in (pci_clk), |
.delete_clk_in (wb_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_wb_err_cs_bit8), |
.block_set_out (block_set_wb_err_cs_bit8), |
.delete_in (delete_wb_err_cs_bit8) |
); |
// Setting FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_wb_err_cs_bit8 <= 1'b0 ; |
else |
begin |
if (wb_error_sig && wb_err_cs_bit0) // Synchronous set |
set_wb_err_cs_bit8 <= 1'b1 ; |
else if (delete_set_wb_err_cs_bit8) // Synchronous reset |
set_wb_err_cs_bit8 <= 1'b0 ; |
end |
end |
wire wb_err_cs_bits = set_wb_err_cs_bit8 && !block_set_wb_err_cs_bit8 ; |
wire meta_wb_err_cs_bits ; |
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(1,0) wb_err_cs_bits_sync |
( |
.data_in (wb_err_cs_bits), |
.clk_out (wb_clk), |
.sync_data_out (meta_wb_err_cs_bits), |
.async_reset (reset) |
) ; |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) |
wb_err_cs_bit8 <= 1'b0 ; |
else |
wb_err_cs_bit8 <= meta_wb_err_cs_bits ; |
end |
`else // GUEST |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
wb_err_cs_bit8 <= 1'b0 ; |
else |
begin |
if (wb_error_sig && wb_err_cs_bit0) // Synchronous set |
wb_err_cs_bit8 <= 1'b1 ; |
else if (delete_wb_err_cs_bit8) // Synchronous reset |
wb_err_cs_bit8 <= 1'b0 ; |
end |
end |
`endif |
`endif |
/* // Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
wb_err_cs_bit10 <= 1'b0 ; |
else |
begin |
if (wb_error_sig) // Synchronous report |
wb_err_cs_bit10 <= wb_error_rty_exp ; |
end |
end */ |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
wb_err_cs_bit9 <= 1'b0 ; |
else |
begin |
if (wb_error_sig) // Synchronous report |
wb_err_cs_bit9 <= wb_error_es ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
begin |
wb_err_cs_bit31_24 <= 8'h00 ; |
wb_err_addr <= 32'h0000_0000 ; |
wb_err_data <= 32'h0000_0000 ; |
end |
else |
if (wb_error_sig) |
begin |
wb_err_cs_bit31_24 <= { wb_error_be, wb_error_bc } ; |
wb_err_addr <= wb_error_addr ; |
wb_err_data <= wb_error_data ; |
end |
end |
|
// SERR_INT and PERR_INT STATUS BITS of ISR - interrupt status register |
`ifdef SYNCHRONEOUS_CLOCK_DOMAINS |
`ifdef HOST |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
isr_bit4_3[4] <= 1'b0 ; |
else |
begin |
if (isr_sys_err_int && icr_bit4_3[4]) // Synchronous set |
isr_bit4_3[4] <= 1'b1 ; |
else if (delete_isr_bit4) // Synchronous reset |
isr_bit4_3[4] <= 1'b0 ; |
end |
end |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
isr_bit4_3[3] <= 1'b0 ; |
else |
begin |
if (isr_par_err_int && icr_bit4_3[3]) // Synchronous set |
isr_bit4_3[3] <= 1'b1 ; |
else if (delete_isr_bit3) // Synchronous reset |
isr_bit4_3[3] <= 1'b0 ; |
end |
end |
`endif |
`else // not SYNCHRONEOUS_CLOCK_DOMAINS |
`ifdef HOST |
reg [4:3] set_isr_bit4_3; |
wire delete_set_isr_bit4; |
wire delete_set_isr_bit3; |
wire block_set_isr_bit4; |
wire block_set_isr_bit3; |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_isr_4 |
( |
.set_clk_in (pci_clk), |
.delete_clk_in (wb_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_isr_bit4), |
.block_set_out (block_set_isr_bit4), |
.delete_in (delete_isr_bit4) |
); |
// Setting FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_isr_bit4_3[4] <= 1'b0 ; |
else |
begin |
if (isr_sys_err_int && icr_bit4_3[4]) // Synchronous set |
set_isr_bit4_3[4] <= 1'b1 ; |
else if (delete_set_isr_bit4) // Synchronous reset |
set_isr_bit4_3[4] <= 1'b0 ; |
end |
end |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_isr_3 |
( |
.set_clk_in (pci_clk), |
.delete_clk_in (wb_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_isr_bit3), |
.block_set_out (block_set_isr_bit3), |
.delete_in (delete_isr_bit3) |
); |
// Setting FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_isr_bit4_3[3] <= 1'b0 ; |
else |
begin |
if (isr_par_err_int && icr_bit4_3[3]) // Synchronous set |
set_isr_bit4_3[3] <= 1'b1 ; |
else if (delete_set_isr_bit3) // Synchronous reset |
set_isr_bit4_3[3] <= 1'b0 ; |
end |
end |
wire [4:3] isr_bits4_3 = {set_isr_bit4_3[4] && !block_set_isr_bit4, |
set_isr_bit4_3[3] && !block_set_isr_bit3 } ; |
wire [4:3] meta_isr_bits4_3 ; |
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(2, 0) isr_bits_sync |
( |
.data_in (isr_bits4_3), |
.clk_out (wb_clk), |
.sync_data_out (meta_isr_bits4_3), |
.async_reset (reset) |
) ; |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) |
isr_bit4_3[4:3] <= 2'b0 ; |
else |
isr_bit4_3[4:3] <= meta_isr_bits4_3[4:3] ; |
end |
`endif |
`endif |
|
// PCI_EINT and WB_EINT STATUS BITS of ISR - interrupt status register |
`ifdef SYNCHRONEOUS_CLOCK_DOMAINS |
// WB_EINT STATUS BIT |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
isr_bit2_0[1] <= 1'b0 ; |
else |
begin |
if (wb_error_sig && icr_bit2_0[1] && wb_err_cs_bit0) // Synchronous set |
isr_bit2_0[1] <= 1'b1 ; |
else if (delete_isr_bit1) // Synchronous reset |
isr_bit2_0[1] <= 1'b0 ; |
end |
end |
// PCI_EINT STATUS BIT |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
isr_bit2_0[2] <= 1'b0 ; |
else |
begin |
if (pci_error_sig && icr_bit2_0[2] && pci_err_cs_bit0) // Synchronous set |
isr_bit2_0[2] <= 1'b1 ; |
else if (delete_isr_bit2) // Synchronous reset |
isr_bit2_0[2] <= 1'b0 ; |
end |
end |
`else // not SYNCHRONEOUS_CLOCK_DOMAINS |
`ifdef HOST |
// WB_EINT STATUS BIT |
reg set_isr_bit1; |
wire delete_set_isr_bit1; |
wire block_set_isr_bit1; |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_isr_1 |
( |
.set_clk_in (pci_clk), |
.delete_clk_in (wb_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_isr_bit1), |
.block_set_out (block_set_isr_bit1), |
.delete_in (delete_isr_bit1) |
); |
// Setting FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_isr_bit1 <= 1'b0 ; |
else |
begin |
if (wb_error_sig && icr_bit2_0[1] && wb_err_cs_bit0) // Synchronous set |
set_isr_bit1 <= 1'b1 ; |
else if (delete_set_isr_bit1) // Synchronous reset |
set_isr_bit1 <= 1'b0 ; |
end |
end |
wire isr_bit1 = set_isr_bit1 && !block_set_isr_bit1 ; |
wire meta_isr_bit1 ; |
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(1, 0) isr_bit1_sync |
( |
.data_in (isr_bit1), |
.clk_out (wb_clk), |
.sync_data_out (meta_isr_bit1), |
.async_reset (reset) |
) ; |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) |
isr_bit2_0[1] <= 1'b0 ; |
else |
isr_bit2_0[1] <= meta_isr_bit1 ; |
end |
// PCI_EINT STATUS BIT |
// Set and clear FF |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
isr_bit2_0[2] <= 1'b0 ; |
else |
begin |
if (pci_error_sig && icr_bit2_0[2] && pci_err_cs_bit0) // Synchronous set |
isr_bit2_0[2] <= 1'b1 ; |
else if (delete_isr_bit2) // Synchronous reset |
isr_bit2_0[2] <= 1'b0 ; |
end |
end |
`else // GUEST |
// WB_EINT STATUS BIT |
// Set and clear FF |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
isr_bit2_0[1] <= 1'b0 ; |
else |
begin |
if (wb_error_sig && icr_bit2_0[1] && wb_err_cs_bit0) // Synchronous set |
isr_bit2_0[1] <= 1'b1 ; |
else if (delete_isr_bit1) // Synchronous reset |
isr_bit2_0[1] <= 1'b0 ; |
end |
end |
// PCI_EINT STATUS BIT |
reg set_isr_bit2; |
wire delete_set_isr_bit2; |
wire block_set_isr_bit2; |
// Synchronization module for clearing FF between two clock domains |
pci_sync_module sync_isr_2 |
( |
.set_clk_in (wb_clk), |
.delete_clk_in (pci_clk), |
.reset_in (reset), |
.delete_set_out (delete_set_isr_bit2), |
.block_set_out (block_set_isr_bit2), |
.delete_in (delete_isr_bit2) |
); |
// Setting FF |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
set_isr_bit2 <= 1'b0 ; |
else |
begin |
if (pci_error_sig && icr_bit2_0[2] && pci_err_cs_bit0) // Synchronous set |
set_isr_bit2 <= 1'b1 ; |
else if (delete_set_isr_bit2) // Synchronous reset |
set_isr_bit2 <= 1'b0 ; |
end |
end |
wire isr_bit2 = set_isr_bit2 && !block_set_isr_bit2 ; |
wire meta_isr_bit2 ; |
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(1, 0) isr_bit2_sync |
( |
.data_in (isr_bit2), |
.clk_out (pci_clk), |
.sync_data_out (meta_isr_bit2), |
.async_reset (reset) |
) ; |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) |
isr_bit2_0[2] <= 1'b0 ; |
else |
isr_bit2_0[2] <= meta_isr_bit2 ; |
end |
`endif |
`endif |
|
// INT BIT of ISR - interrupt status register |
`ifdef HOST |
wire isr_int_prop_bit = isr_int_prop && icr_bit2_0[0] ; |
wire meta_isr_int_prop_bit ; |
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(1, 0) isr_bit0_sync |
( |
.data_in (isr_int_prop_bit), |
.clk_out (wb_clk), |
.sync_data_out (meta_isr_int_prop_bit), |
.async_reset (reset) |
) ; |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) |
isr_bit2_0[0] <= 1'b0 ; |
else |
isr_bit2_0[0] <= meta_isr_int_prop_bit ; |
end |
`else // GUEST |
`ifdef SYNCHRONEOUS_CLOCK_DOMAINS |
wire isr_int_prop_bit = isr_int_prop && icr_bit2_0[0] ; |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) |
isr_bit2_0[0] <= 1'b0 ; |
else |
isr_bit2_0[0] <= isr_int_prop_bit ; |
end |
`else // not SYNCHRONEOUS_CLOCK_DOMAINS |
wire isr_int_prop_bit = isr_int_prop && icr_bit2_0[0] ; |
wire meta_isr_int_prop_bit ; |
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(1, 0) isr_bit0_sync |
( |
.data_in (isr_int_prop_bit), |
.clk_out (pci_clk), |
.sync_data_out (meta_isr_int_prop_bit), |
.async_reset (reset) |
) ; |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) |
isr_bit2_0[0] <= 1'b0 ; |
else |
isr_bit2_0[0] <= meta_isr_int_prop_bit ; |
end |
`endif |
`endif |
|
// INT PIN |
wire int_in; |
wire int_meta; |
reg interrupt_out; |
`ifdef HOST |
`ifdef SYNCHRONEOUS_CLOCK_DOMAINS |
assign int_in = isr_int_prop_bit || isr_bit2_0[1] || isr_bit2_0[2] || isr_bit4_3[3] || isr_bit4_3[4]; |
`else // not SYNCHRONEOUS_CLOCK_DOMAINS |
assign int_in = isr_int_prop_bit || isr_bit1 || isr_bit2_0[2] || isr_bits4_3[3] || isr_bits4_3[4]; |
`endif |
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(1, 0) int_pin_sync |
( |
.data_in (int_in), |
.clk_out (wb_clk), |
.sync_data_out (int_meta), |
.async_reset (reset) |
) ; |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) |
interrupt_out <= 1'b0 ; |
else |
interrupt_out <= int_meta ; |
end |
`else // GUEST |
`ifdef SYNCHRONEOUS_CLOCK_DOMAINS |
assign int_in = isr_int_prop_bit || isr_bit2_0[1] || isr_bit2_0[2]; |
`else // not SYNCHRONEOUS_CLOCK_DOMAINS |
assign int_in = isr_int_prop_bit || isr_bit2_0[1] || isr_bit2; |
`endif |
// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability |
pci_synchronizer_flop #(1, 0) int_pin_sync |
( |
.data_in (int_in), |
.clk_out (pci_clk), |
.sync_data_out (int_meta), |
.async_reset (reset) |
) ; |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) |
interrupt_out <= 1'b0 ; |
else |
interrupt_out <= int_meta ; |
end |
`endif |
|
/*----------------------------------------------------------------------------------------------------------- |
OUTPUTs from registers !!! |
-----------------------------------------------------------------------------------------------------------*/ |
|
// if bridge is HOST then write clock is equal to WB clock, and synchronization of outputs has to be done |
`ifdef HOST |
wire [3:0] command_bits = {command_bit8, command_bit6, command_bit2_0[1:0]} ; |
wire [3:0] meta_command_bits ; |
reg [3:0] sync_command_bits ; |
pci_synchronizer_flop #(4, 0) command_bits_sync |
( |
.data_in (command_bits), |
.clk_out (pci_clk), |
.sync_data_out (meta_command_bits), |
.async_reset (reset) |
) ; |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) |
sync_command_bits <= 4'b0 ; |
else |
sync_command_bits <= meta_command_bits ; |
end |
wire sync_command_bit8 = sync_command_bits[3] ; |
wire sync_command_bit6 = sync_command_bits[2] ; |
wire sync_command_bit1 = sync_command_bits[1] ; |
wire sync_command_bit0 = sync_command_bits[0] ; |
wire sync_command_bit2 = command_bit2_0[2] ; |
`else // GUEST |
wire command_bit = command_bit2_0[2] ; |
wire meta_command_bit ; |
reg sync_command_bit ; |
pci_synchronizer_flop #(1, 0) command_bit_sync |
( |
.data_in (command_bit), |
.clk_out (pci_clk), |
.sync_data_out (meta_command_bit), |
.async_reset (reset) |
) ; |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) |
sync_command_bit <= 1'b0 ; |
else |
sync_command_bit <= meta_command_bit ; |
end |
wire sync_command_bit8 = command_bit8 ; |
wire sync_command_bit6 = command_bit6 ; |
wire sync_command_bit1 = command_bit2_0[1] ; |
wire sync_command_bit0 = command_bit2_0[0] ; |
wire sync_command_bit2 = sync_command_bit ; |
`endif |
// PCI header outputs from command register |
assign serr_enable = sync_command_bit8 ; // to PCI clock |
assign perr_response = sync_command_bit6 ; // to PCI clock |
assign pci_master_enable = sync_command_bit2 ; // to WB clock |
assign memory_space_enable = sync_command_bit1 ; // to PCI clock |
assign io_space_enable = sync_command_bit0 ; // to PCI clock |
|
// if bridge is HOST then write clock is equal to WB clock, and synchronization of outputs has to be done |
// We don't support cache line sizes smaller that 4 and it must have last two bits zero!!! |
wire cache_lsize_not_zero = ((cache_line_size_reg[7] || cache_line_size_reg[6] || cache_line_size_reg[5] || |
cache_line_size_reg[4] || cache_line_size_reg[3] || cache_line_size_reg[2]) && |
(!cache_line_size_reg[1] && !cache_line_size_reg[0]) ); |
`ifdef HOST |
wire [7:2] cache_lsize_to_pci_bits = { cache_line_size_reg[7:2] } ; |
wire [7:2] meta_cache_lsize_to_pci_bits ; |
reg [7:2] sync_cache_lsize_to_pci_bits ; |
pci_synchronizer_flop #(6, 0) cache_lsize_to_pci_bits_sync |
( |
.data_in (cache_lsize_to_pci_bits), |
.clk_out (pci_clk), |
.sync_data_out (meta_cache_lsize_to_pci_bits), |
.async_reset (reset) |
) ; |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) |
sync_cache_lsize_to_pci_bits <= 6'b0 ; |
else |
sync_cache_lsize_to_pci_bits <= meta_cache_lsize_to_pci_bits ; |
end |
wire [7:2] sync_cache_line_size_to_pci_reg = sync_cache_lsize_to_pci_bits[7:2] ; |
wire [7:2] sync_cache_line_size_to_wb_reg = cache_line_size_reg[7:2] ; |
wire sync_cache_lsize_not_zero_to_wb = cache_lsize_not_zero ; |
// Latency timer is sinchronized only to PCI clock when bridge implementation is HOST |
wire [7:0] latency_timer_bits = latency_timer ; |
wire [7:0] meta_latency_timer_bits ; |
reg [7:0] sync_latency_timer_bits ; |
pci_synchronizer_flop #(8, 0) latency_timer_bits_sync |
( |
.data_in (latency_timer_bits), |
.clk_out (pci_clk), |
.sync_data_out (meta_latency_timer_bits), |
.async_reset (reset) |
) ; |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) |
sync_latency_timer_bits <= 8'b0 ; |
else |
sync_latency_timer_bits <= meta_latency_timer_bits ; |
end |
wire [7:0] sync_latency_timer = sync_latency_timer_bits ; |
`else // GUEST |
wire [8:2] cache_lsize_to_wb_bits = { cache_lsize_not_zero, cache_line_size_reg[7:2] } ; |
wire [8:2] meta_cache_lsize_to_wb_bits ; |
reg [8:2] sync_cache_lsize_to_wb_bits ; |
pci_synchronizer_flop #(7, 0) cache_lsize_to_wb_bits_sync |
( |
.data_in (cache_lsize_to_wb_bits), |
.clk_out (wb_clk), |
.sync_data_out (meta_cache_lsize_to_wb_bits), |
.async_reset (reset) |
) ; |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) |
sync_cache_lsize_to_wb_bits <= 7'b0 ; |
else |
sync_cache_lsize_to_wb_bits <= meta_cache_lsize_to_wb_bits ; |
end |
wire [7:2] sync_cache_line_size_to_pci_reg = cache_line_size_reg[7:2] ; |
wire [7:2] sync_cache_line_size_to_wb_reg = sync_cache_lsize_to_wb_bits[7:2] ; |
wire sync_cache_lsize_not_zero_to_wb = sync_cache_lsize_to_wb_bits[8] ; |
// Latency timer |
wire [7:0] sync_latency_timer = latency_timer ; |
`endif |
// PCI header output from cache_line_size, latency timer and interrupt pin |
assign cache_line_size_to_pci = {sync_cache_line_size_to_pci_reg, 2'h0} ; // [7 : 0] to PCI clock |
assign cache_line_size_to_wb = {sync_cache_line_size_to_wb_reg, 2'h0} ; // [7 : 0] to WB clock |
assign cache_lsize_not_zero_to_wb = sync_cache_lsize_not_zero_to_wb ; |
|
assign latency_tim[7 : 0] = sync_latency_timer ; // to PCI clock |
//assign int_pin[2 : 0] = r_interrupt_pin ; |
assign int_out = interrupt_out ; |
// PCI output from image registers |
// base address, address mask, translation address and control registers are sinchronized in PCI_DECODER.V module |
assign pci_base_addr0 = pci_ba0_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_base_addr1 = pci_ba1_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_base_addr2 = pci_ba2_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_base_addr3 = pci_ba3_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_base_addr4 = pci_ba4_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_base_addr5 = pci_ba5_bit31_12[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_memory_io0 = pci_ba0_bit0 ; |
assign pci_memory_io1 = pci_ba1_bit0 ; |
assign pci_memory_io2 = pci_ba2_bit0 ; |
assign pci_memory_io3 = pci_ba3_bit0 ; |
assign pci_memory_io4 = pci_ba4_bit0 ; |
assign pci_memory_io5 = pci_ba5_bit0 ; |
assign pci_addr_mask0 = pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_addr_mask1 = pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_addr_mask2 = pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_addr_mask3 = pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_addr_mask4 = pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_addr_mask5 = pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_tran_addr0 = pci_ta0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_tran_addr1 = pci_ta1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_tran_addr2 = pci_ta2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_tran_addr3 = pci_ta3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_tran_addr4 = pci_ta4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_tran_addr5 = pci_ta5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; |
assign pci_img_ctrl0[2 : 1] = pci_img_ctrl0_bit2_1 ; |
assign pci_img_ctrl1[2 : 1] = pci_img_ctrl1_bit2_1 ; |
assign pci_img_ctrl2[2 : 1] = pci_img_ctrl2_bit2_1 ; |
assign pci_img_ctrl3[2 : 1] = pci_img_ctrl3_bit2_1 ; |
assign pci_img_ctrl4[2 : 1] = pci_img_ctrl4_bit2_1 ; |
assign pci_img_ctrl5[2 : 1] = pci_img_ctrl5_bit2_1 ; |
// WISHBONE output from image registers |
// base address, address mask, translation address and control registers are sinchronized in DECODER.V module |
assign wb_base_addr0 = wb_ba0_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_base_addr1 = wb_ba1_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_base_addr2 = wb_ba2_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_base_addr3 = wb_ba3_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_base_addr4 = wb_ba4_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_base_addr5 = wb_ba5_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_memory_io0 = wb_ba0_bit0 ; |
assign wb_memory_io1 = wb_ba1_bit0 ; |
assign wb_memory_io2 = wb_ba2_bit0 ; |
assign wb_memory_io3 = wb_ba3_bit0 ; |
assign wb_memory_io4 = wb_ba4_bit0 ; |
assign wb_memory_io5 = wb_ba5_bit0 ; |
assign wb_addr_mask0 = wb_am0[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_addr_mask1 = wb_am1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_addr_mask2 = wb_am2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_addr_mask3 = wb_am3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_addr_mask4 = wb_am4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_addr_mask5 = wb_am5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_tran_addr0 = wb_ta0[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_tran_addr1 = wb_ta1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_tran_addr2 = wb_ta2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_tran_addr3 = wb_ta3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_tran_addr4 = wb_ta4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_tran_addr5 = wb_ta5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; |
assign wb_img_ctrl0[2 : 0] = wb_img_ctrl0_bit2_0 ; |
assign wb_img_ctrl1[2 : 0] = wb_img_ctrl1_bit2_0 ; |
assign wb_img_ctrl2[2 : 0] = wb_img_ctrl2_bit2_0 ; |
assign wb_img_ctrl3[2 : 0] = wb_img_ctrl3_bit2_0 ; |
assign wb_img_ctrl4[2 : 0] = wb_img_ctrl4_bit2_0 ; |
assign wb_img_ctrl5[2 : 0] = wb_img_ctrl5_bit2_0 ; |
// GENERAL output from conf. cycle generation register & int. control register |
assign config_addr[23 : 0] = { cnf_addr_bit23_2, 1'b0, cnf_addr_bit0 } ; |
assign icr_soft_res = icr_bit31 ; |
|
|
endmodule |
|
/verilog/pci_delayed_sync.v
0,0 → 1,466
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "delayed_sync.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2003/03/26 13:16:18 mihad |
// Added the reset value parameter to the synchronizer flop module. |
// Added resets to all synchronizer flop instances. |
// Repaired initial sync value in fifos. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.5 2002/09/25 09:54:50 mihad |
// Added completion expiration test for WB Slave unit. Changed expiration signalling |
// |
// Revision 1.4 2002/03/05 11:53:47 mihad |
// Added some testcases, removed un-needed fifo signals |
// |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// module provides synchronization mechanism between requesting and completing side of the bridge |
`include "pci_constants.v" |
`include "bus_commands.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_delayed_sync |
( |
reset_in, |
req_clk_in, |
comp_clk_in, |
req_in, |
comp_in, |
done_in, |
in_progress_in, |
comp_req_pending_out, |
req_req_pending_out, |
req_comp_pending_out, |
comp_comp_pending_out, |
addr_in, |
be_in, |
addr_out, |
be_out, |
we_in, |
we_out, |
bc_in, |
bc_out, |
status_in, |
status_out, |
comp_flush_out, |
burst_in, |
burst_out, |
retry_expired_in |
); |
|
// system inputs |
input reset_in, // reset input |
req_clk_in, // requesting clock input |
comp_clk_in ; // completing clock input |
|
// request, completion, done and in progress indication inputs |
input req_in, // request qualifier - when 1 it indicates that valid request data is provided on inputs |
comp_in, // completion qualifier - when 1, completing side indicates that request has completed |
done_in, // done input - when 1 indicates that requesting side of the bridge has completed a transaction on requesting bus |
in_progress_in ; // in progress indicator - indicates that current completion is in progress on requesting side of the bridge |
|
// pending indication outputs |
output comp_req_pending_out, // completion side request output - resynchronized from requesting clock to completing clock |
req_req_pending_out, // request pending output for requesting side |
req_comp_pending_out, // completion pending output for requesting side of the bridge - it indicates when completion is ready for completing on requesting bus |
comp_comp_pending_out ; // completion pending output for completing side of the bridge |
|
// additional signals and wires for clock domain passage of signals |
reg comp_req_pending, |
req_req_pending, |
req_comp_pending, |
req_comp_pending_sample, |
comp_comp_pending, |
req_done_reg, |
comp_done_reg_main, |
comp_done_reg_clr, |
req_rty_exp_reg, |
req_rty_exp_clr, |
comp_rty_exp_reg, |
comp_rty_exp_clr ; |
|
wire sync_comp_req_pending, |
sync_req_comp_pending, |
sync_comp_done, |
sync_req_rty_exp, |
sync_comp_rty_exp_clr ; |
|
// inputs from requesting side - only this side can set address, bus command, byte enables, write enable and burst - outputs are common for both sides |
// all signals that identify requests are stored in this module |
|
input [31:0] addr_in ; // address bus input |
input [3:0] be_in ; // byte enable input |
input we_in ; // write enable input - read/write request indication 1 = write request / 0 = read request |
input [3:0] bc_in ; // bus command input |
input burst_in ; // burst indicator - qualifies operation as burst/single transfer 1 = burst / 0 = single transfer |
|
// common request outputs used both by completing and requesting sides |
// this outputs are not resynchronized, since flags determine the request status |
output [31:0] addr_out ; |
output [3:0] be_out ; |
output we_out ; |
output [3:0] bc_out ; |
output burst_out ; |
|
// completion side signals encoded termination status - 0 = normal completion / 1 = error terminated completion |
input status_in ; |
output status_out ; |
|
// input signals that delayed transaction has been retried for max number of times |
// on this signal request is ditched, otherwise it would cause a deadlock |
// requestor can issue another request and procedure will be repeated |
input retry_expired_in ; |
|
// completion flush output - if in 2^^16 clock cycles transaction is not repeated by requesting agent - flush completion data |
output comp_flush_out ; |
|
// output registers for common signals |
reg [31:0] addr_out ; |
reg [3:0] be_out ; |
reg we_out ; |
reg [3:0] bc_out ; |
reg burst_out ; |
|
// delayed transaction information is stored only when request is issued and request nor completion are pending |
wire new_request = req_in && ~req_comp_pending_out && ~req_req_pending_out ; |
always@(posedge req_clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
addr_out <= #`FF_DELAY 32'h0000_0000 ; |
be_out <= #`FF_DELAY 4'h0 ; |
we_out <= #`FF_DELAY 1'b0 ; |
bc_out <= #`FF_DELAY `BC_RESERVED0 ; |
burst_out <= #`FF_DELAY 1'b0 ; |
end |
else |
if (new_request) |
begin |
addr_out <= #`FF_DELAY addr_in ; |
be_out <= #`FF_DELAY be_in ; |
we_out <= #`FF_DELAY we_in ; |
bc_out <= #`FF_DELAY bc_in ; |
burst_out <= #`FF_DELAY burst_in ; |
end |
end |
|
// completion pending cycle counter |
reg [16:0] comp_cycle_count ; |
|
/*================================================================================================================================= |
Passing of requests between clock domains: |
request originates on requesting side. It's then synchronized with two flip-flops to cross to completing clock domain |
=================================================================================================================================*/ |
// main request flip-flop triggered on requesting side's clock |
// request is cleared whenever completion or retry expired is signalled from opposite side of the bridge |
wire req_req_clear = req_comp_pending || (req_rty_exp_reg && ~req_rty_exp_clr) ; |
always@(posedge req_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
req_req_pending <= #`FF_DELAY 1'b0 ; |
else |
if ( req_req_clear ) |
req_req_pending <= #`FF_DELAY 1'b0 ; |
else |
if ( req_in ) |
req_req_pending <= #`FF_DELAY 1'b1 ; |
end |
|
// interemediate stage request synchronization flip - flop - this one is prone to metastability |
// and should have setup and hold times disabled during simulation |
pci_synchronizer_flop #(1, 0) req_sync |
( |
.data_in (req_req_pending), |
.clk_out (comp_clk_in), |
.sync_data_out (sync_comp_req_pending), |
.async_reset (reset_in) |
) ; |
|
// wire for clearing completion side request flag - whenever completion or retry expired are signalled |
wire comp_req_pending_clear = comp_req_pending && ( comp_in || retry_expired_in) ; |
|
// wire for enabling request flip - flop - it is enabled when completion is not active and done is not active |
wire comp_req_pending_ena = ~comp_comp_pending && ~comp_done_reg_main && ~comp_rty_exp_reg ; |
|
// completion side request flip flop - gets a value from intermediate stage sync flip flop |
always@(posedge comp_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
comp_req_pending <= #`FF_DELAY 1'b0 ; |
else |
if ( comp_req_pending_clear ) |
comp_req_pending <= #`FF_DELAY 1'b0 ; |
else |
if ( comp_req_pending_ena ) |
comp_req_pending <= #`FF_DELAY sync_comp_req_pending ; |
end |
|
// completion side request output assignment - when request ff is set and completion ff is not set |
assign comp_req_pending_out = comp_req_pending ; |
|
// requesting side request pending output |
assign req_req_pending_out = req_req_pending ; |
/*================================================================================================================================= |
Passing of completions between clock domains: |
completion originates on completing side. It's then synchronized with two flip-flops to cross to requesting clock domain |
=================================================================================================================================*/ |
// main completion Flip - Flop - triggered by completing side's clock |
// completion side completion pending flag is cleared when done flag propagates through clock domains |
wire comp_comp_clear = comp_done_reg_main && ~comp_done_reg_clr ; |
always@(posedge comp_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
comp_comp_pending <= #`FF_DELAY 1'b0 ; |
else |
if ( comp_comp_clear ) |
comp_comp_pending <= #`FF_DELAY 1'b0 ; |
else |
if ( comp_in && comp_req_pending ) |
comp_comp_pending <= #`FF_DELAY 1'b1 ; |
end |
|
assign comp_comp_pending_out = comp_comp_pending ; |
|
// interemediate stage completion synchronization flip - flop - this one is prone to metastability |
pci_synchronizer_flop #(1, 0) comp_sync |
( |
.data_in (comp_comp_pending), |
.clk_out (req_clk_in), |
.sync_data_out (sync_req_comp_pending), |
.async_reset (reset_in) |
) ; |
|
// request side completion pending flip flop is cleared whenever done is signalled or completion counter expires - 2^^16 clock cycles |
wire req_comp_pending_clear = done_in || comp_cycle_count[16]; |
|
// request side completion pending flip flop is disabled while done flag is set |
wire req_comp_pending_ena = ~req_done_reg ; |
|
// request side completion flip flop - gets a value from intermediate stage sync flip flop |
always@(posedge req_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
req_comp_pending <= #`FF_DELAY 1'b0 ; |
else |
if ( req_comp_pending_clear ) |
req_comp_pending <= #`FF_DELAY 1'b0 ; |
else |
if ( req_comp_pending_ena ) |
req_comp_pending <= #`FF_DELAY sync_req_comp_pending ; |
end |
|
// sampling FF - used for sampling incoming completion flag from completing side |
always@(posedge req_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
req_comp_pending_sample <= #`FF_DELAY 1'b0 ; |
else |
req_comp_pending_sample <= #`FF_DELAY sync_req_comp_pending ; |
end |
|
// requesting side completion pending output assignment |
assign req_comp_pending_out = req_comp_pending && ~req_req_pending ; |
|
/*================================================================================================================================== |
Passing of delayed transaction done signal between clock domains. |
Done is signalled by requesting side of the bridge and is passed to completing side of the bridge |
==================================================================================================================================*/ |
// main done flip-flop triggered on requesting side's clock |
// when completing side removes completion flag, done flag is also removed, so requests can proceede |
wire req_done_clear = ~req_comp_pending_sample ; |
always@(posedge req_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
req_done_reg <= #`FF_DELAY 1'b0 ; |
else |
if ( req_done_clear ) |
req_done_reg <= #`FF_DELAY 1'b0 ; |
else |
if ( done_in || comp_cycle_count[16] ) |
req_done_reg <= #`FF_DELAY 1'b1 ; |
end |
|
pci_synchronizer_flop #(1, 0) done_sync |
( |
.data_in (req_done_reg), |
.clk_out (comp_clk_in), |
.sync_data_out (sync_comp_done), |
.async_reset (reset_in) |
) ; |
|
always@(posedge comp_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
comp_done_reg_main <= #`FF_DELAY 1'b0 ; |
else |
comp_done_reg_main <= #`FF_DELAY sync_comp_done ; |
end |
|
always@(posedge comp_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
comp_done_reg_clr <= #`FF_DELAY 1'b0 ; |
else |
comp_done_reg_clr <= #`FF_DELAY comp_done_reg_main ; |
end |
|
/*================================================================================================================================= |
Passing of retry expired signal between clock domains |
Retry expiration originates on completing side. It's then synchronized with two flip-flops to cross to requesting clock domain |
=================================================================================================================================*/ |
// main retry expired Flip - Flop - triggered by completing side's clock |
wire comp_rty_exp_clear = comp_rty_exp_clr && comp_rty_exp_reg ; |
|
// retry expired is a special case of transaction removal - retry expired propagates from completing |
// clock domain to requesting clock domain to remove all pending requests and than propagates back |
// to completing side to qualify valid new requests |
|
always@(posedge comp_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
comp_rty_exp_reg <= #`FF_DELAY 1'b0 ; |
else |
if ( comp_rty_exp_clear ) |
comp_rty_exp_reg <= #`FF_DELAY 1'b0 ; |
else |
if ( retry_expired_in && comp_req_pending) |
comp_rty_exp_reg <= #`FF_DELAY 1'b1 ; |
end |
|
// interemediate stage retry expired synchronization flip - flop - this one is prone to metastability |
pci_synchronizer_flop #(1, 0) rty_exp_sync |
( |
.data_in (comp_rty_exp_reg), |
.clk_out (req_clk_in), |
.sync_data_out (sync_req_rty_exp), |
.async_reset (reset_in) |
) ; |
|
// request retry expired flip flop - gets a value from intermediate stage sync flip flop |
always@(posedge req_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
req_rty_exp_reg <= #`FF_DELAY 1'b0 ; |
else |
req_rty_exp_reg <= #`FF_DELAY sync_req_rty_exp ; |
end |
|
always@(posedge req_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
req_rty_exp_clr <= #`FF_DELAY 1'b0 ; |
else |
req_rty_exp_clr <= #`FF_DELAY req_rty_exp_reg ; |
end |
|
pci_synchronizer_flop #(1, 0) rty_exp_back_prop_sync |
( |
.data_in (req_rty_exp_reg && req_rty_exp_clr), |
.clk_out (comp_clk_in), |
.sync_data_out (sync_comp_rty_exp_clr), |
.async_reset (reset_in) |
) ; |
|
always@(posedge comp_clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
comp_rty_exp_clr <= #`FF_DELAY 1'b0 ; |
else |
comp_rty_exp_clr <= #`FF_DELAY sync_comp_rty_exp_clr ; |
end |
|
// completion status flip flop - if 0 when completion is signalled it's finished OK otherwise it means error |
reg status_out ; |
always@(posedge comp_clk_in or posedge reset_in) |
begin |
if (reset_in) |
status_out <= #`FF_DELAY 1'b0 ; |
else |
if (comp_in && comp_req_pending) |
status_out <= #`FF_DELAY status_in ; |
end |
|
// clocks counter - it counts how many clock cycles completion is present without beeing repeated |
// if it counts to 2^^16 cycles the completion must be ditched |
|
// wire for clearing this counter |
wire clear_count = in_progress_in || ~req_comp_pending_out || comp_cycle_count[16] ; |
always@(posedge req_clk_in or posedge reset_in) |
begin |
if (reset_in) |
comp_cycle_count <= #`FF_DELAY 17'h0_0000 ; |
else |
if (clear_count) |
comp_cycle_count <= #`FF_DELAY 17'h0_0000 ; |
else |
comp_cycle_count <= #`FF_DELAY comp_cycle_count + 1'b1 ; |
end |
|
// completion flush output - used for flushing fifos when counter expires |
// if counter doesn't expire, fifo flush is up to WISHBONE slave or PCI target state machines |
reg comp_flush_out ; |
always@(posedge req_clk_in or posedge reset_in) |
begin |
if (reset_in) |
comp_flush_out <= #`FF_DELAY 1'b0 ; |
else |
comp_flush_out <= #`FF_DELAY comp_cycle_count[16] ; |
end |
|
endmodule //delayed_sync |
/verilog/pci_synchronizer_flop.v
0,0 → 1,100
//=========================================================================== |
// $Id: pci_synchronizer_flop.v,v 1.1 2003-08-14 13:08:58 simons Exp $ |
// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// pci_synchronizer_flop //// |
//// //// |
//// This file is part of the general opencores effort. //// |
//// <http://www.opencores.org/cores/misc/> //// |
//// //// |
//// Module Description: //// |
//// //// |
//// Make a rising-edge triggered flop with async reset with a //// |
//// distinguished name so that it can be replaced with a flop //// |
//// which does not make X's during simulation. //// |
//// //// |
//// This flop should be used instead of a regular flop for ALL //// |
//// cross-clock-domain flops. Manually instantiating this //// |
//// flop for all signals which must NEVER go to 1'bX during //// |
//// simulation will make it possible for the user to //// |
//// substitute a simulation model which does NOT have setup //// |
//// and hold checks. //// |
//// //// |
//// If a target device library has a component which is //// |
//// especially well suited to perform this function, it should //// |
//// be instantiated by name in this file. Otherwise, the //// |
//// behaviorial version of this module will be used. //// |
//// //// |
//// To Do: //// |
//// Nothing //// |
//// //// |
//// Author(s): //// |
//// - anynomous //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// If the vendor has a flop which is particularly good at settling out of |
// metastability, it should be used here. |
module pci_synchronizer_flop ( |
data_in, clk_out, sync_data_out, async_reset |
); |
parameter width = 1 ; |
parameter reset_val = 0 ; |
|
input [width-1:0] data_in; |
input clk_out; |
output [width-1:0] sync_data_out; |
input async_reset; |
|
reg [width-1:0] sync_data_out; |
|
always @(posedge clk_out or posedge async_reset) |
begin |
if (async_reset == 1'b1) |
begin |
sync_data_out <= reset_val; |
end |
else |
begin |
// In gate-level simulation, must only go to 1'bX if the input is 1'bX or 1'bZ. |
// This should NEVER go to 1'bX due to setup or hold violations. |
sync_data_out <= data_in; |
end |
end |
endmodule |
|
/verilog/pci_wbw_fifo_control.v
0,0 → 1,297
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "wbw_fifo_control.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2003/07/29 08:20:11 mihad |
// Found and simulated the problem in the synchronization logic. |
// Repaired the synchronization logic in the FIFOs. |
// |
// Revision 1.2 2003/03/26 13:16:18 mihad |
// Added the reset value parameter to the synchronizer flop module. |
// Added resets to all synchronizer flop instances. |
// Repaired initial sync value in fifos. |
// |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.6 2002/11/27 20:36:13 mihad |
// Changed the code a bit to make it more readable. |
// Functionality not changed in any way. |
// More robust synchronization in fifos is still pending. |
// |
// Revision 1.5 2002/09/30 16:03:04 mihad |
// Added meta flop module for easier meta stable FF identification during synthesis |
// |
// Revision 1.4 2002/09/25 15:53:52 mihad |
// Removed all logic from asynchronous reset network |
// |
// Revision 1.3 2002/02/01 15:25:14 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
/* FIFO_CONTROL module provides read/write address and status generation for |
FIFOs implemented with standard dual port SRAM cells in ASIC or FPGA designs */ |
`include "pci_constants.v" |
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_wbw_fifo_control |
( |
rclock_in, |
wclock_in, |
renable_in, |
wenable_in, |
reset_in, |
almost_full_out, |
full_out, |
empty_out, |
waddr_out, |
raddr_out, |
rallow_out, |
wallow_out |
); |
|
parameter ADDR_LENGTH = 7 ; |
|
// independent clock inputs - rclock_in = read clock, wclock_in = write clock |
input rclock_in, wclock_in; |
|
// enable inputs - read address changes on rising edge of rclock_in when reads are allowed |
// write address changes on rising edge of wclock_in when writes are allowed |
input renable_in, wenable_in ; |
|
// reset input |
input reset_in; |
|
// flush input |
// input flush_in ; // not used |
|
// almost full and empy status outputs |
output almost_full_out ; |
|
// full and empty status outputs |
output full_out, empty_out; |
|
// read and write addresses outputs |
output [(ADDR_LENGTH - 1):0] waddr_out, raddr_out; |
|
// read and write allow outputs |
output rallow_out, wallow_out ; |
|
// read address register |
reg [(ADDR_LENGTH - 1):0] raddr ; |
|
// write address register |
reg [(ADDR_LENGTH - 1):0] waddr; |
assign waddr_out = waddr ; |
|
// grey code registers |
reg [(ADDR_LENGTH - 1):0] wgrey_addr ; // current |
// grey code register for next write address |
reg [(ADDR_LENGTH - 1):0] wgrey_next ; // next |
|
// next write gray address calculation - bitwise xor between address and shifted address |
wire [(ADDR_LENGTH - 2):0] calc_wgrey_next = waddr[(ADDR_LENGTH - 1):1] ^ waddr[(ADDR_LENGTH - 2):0] ; |
|
// grey code pipeline for read address |
reg [(ADDR_LENGTH - 1):0] rgrey_minus1 ; // one before current |
reg [(ADDR_LENGTH - 1):0] rgrey_addr ; // current |
reg [(ADDR_LENGTH - 1):0] rgrey_next ; // next |
|
// next read gray address calculation - bitwise xor between address and shifted address |
wire [(ADDR_LENGTH - 2):0] calc_rgrey_next = raddr[(ADDR_LENGTH - 1):1] ^ raddr[(ADDR_LENGTH - 2):0] ; |
|
// write allow wire - writes are allowed when fifo is not full |
assign wallow_out = wenable_in & ~full_out ; |
|
// clear generation for FFs and registers |
wire clear = reset_in ; |
|
//rallow generation |
assign rallow_out = renable_in & ~empty_out ; // reads allowed if read enable is high and FIFO is not empty |
|
// at any clock edge that rallow is high, this register provides next read address, so wait cycles are not necessary |
// when FIFO is empty, this register provides actual read address, so first location can be read |
reg [(ADDR_LENGTH - 1):0] raddr_plus_one ; |
|
// address output mux - when FIFO is empty, current actual address is driven out, when it is non - empty next address is driven out |
// done for zero wait state burst |
assign raddr_out = rallow_out ? raddr_plus_one : raddr ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
raddr_plus_one <= #`FF_DELAY 4 ; |
raddr <= #`FF_DELAY 3 ; |
end |
else if (rallow_out) |
begin |
raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ; |
raddr <= #`FF_DELAY raddr_plus_one ; |
end |
end |
|
/*----------------------------------------------------------------------------------------------- |
Read address control consists of Read address counter and Grey Address pipeline |
There are 3 Grey addresses: |
- rgrey_minus1 is Grey Code of address one before current address |
- rgrey_addr is Grey Code of current read address |
- rgrey_next is Grey Code of next read address |
--------------------------------------------------------------------------------------------------*/ |
// grey coded address pipeline for status generation in read clock domain |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 0 |
rgrey_minus1 <= #1 0 ; |
rgrey_addr <= #1 1 ; |
rgrey_next <= #`FF_DELAY 3 ; |
end |
else |
if (rallow_out) |
begin |
rgrey_minus1 <= #1 rgrey_addr ; |
rgrey_addr <= #1 rgrey_next ; |
rgrey_next <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ; |
end |
end |
|
/*-------------------------------------------------------------------------------------------- |
Write address control consists of write address counter and Grey Code Register |
----------------------------------------------------------------------------------------------*/ |
// grey coded address pipeline for status generation in write clock domain |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
wgrey_addr <= #`FF_DELAY 1 ; |
wgrey_next <= #1 3 ; |
end |
else |
if (wallow_out) |
begin |
wgrey_addr <= #`FF_DELAY wgrey_next ; |
wgrey_next <= #1 {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ; |
end |
end |
|
// write address counter - nothing special - initial value is important though |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
// initial value 4 |
waddr <= #`FF_DELAY 3 ; |
else |
if (wallow_out) |
waddr <= #`FF_DELAY waddr + 1'b1 ; |
end |
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Gray coded address of read address decremented by 1 is synchronized to write clock domain and compared to: |
|
- Gray coded write address. If they are equal, fifo is full. |
|
- Gray coded next write address. If they are equal, fifo is almost full. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_minus1 ; |
reg [(ADDR_LENGTH - 1):0] wclk_rgrey_minus1 ; |
|
pci_synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_rgrey_minus1 |
( |
.data_in (rgrey_minus1), |
.clk_out (wclock_in), |
.sync_data_out (wclk_sync_rgrey_minus1), |
.async_reset (clear) |
) ; |
|
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
wclk_rgrey_minus1 <= #`FF_DELAY 0 ; |
end |
else |
begin |
wclk_rgrey_minus1 <= #`FF_DELAY wclk_sync_rgrey_minus1 ; |
end |
end |
|
assign full_out = (wgrey_addr == wclk_rgrey_minus1) ; |
assign almost_full_out = (wgrey_next == wclk_rgrey_minus1) ; |
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Empty control: |
Gray coded address of next write address is synchronized to read clock domain and compared to Gray coded next read address. |
If they are equal, fifo is empty. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
wire [(ADDR_LENGTH - 1):0] rclk_sync_wgrey_next ; |
reg [(ADDR_LENGTH - 1):0] rclk_wgrey_next ; |
pci_synchronizer_flop #(ADDR_LENGTH, 3) i_synchronizer_reg_wgrey_next |
( |
.data_in (wgrey_next), |
.clk_out (rclock_in), |
.sync_data_out (rclk_sync_wgrey_next), |
.async_reset (clear) |
) ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
rclk_wgrey_next <= #`FF_DELAY 3 ; |
else |
rclk_wgrey_next <= #`FF_DELAY rclk_sync_wgrey_next ; |
end |
|
assign empty_out = (rgrey_next == rclk_wgrey_next) ; |
|
endmodule |
/verilog/pci_pciw_fifo_control.v
0,0 → 1,320
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pciw_fifo_control.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2003/08/08 16:36:33 tadejm |
// Added 'three_left_out' to pci_pciw_fifo signaling three locations before full. Added comparison between current registered cbe and next unregistered cbe to signal wb_master whether it is allowed to performe burst or not. Due to this, I needed 'three_left_out' so that writing to pci_pciw_fifo can be registered, otherwise timing problems would occure. |
// |
// Revision 1.3 2003/07/29 08:20:11 mihad |
// Found and simulated the problem in the synchronization logic. |
// Repaired the synchronization logic in the FIFOs. |
// |
// |
|
/* FIFO_CONTROL module provides read/write address and status generation for |
FIFOs implemented with standard dual port SRAM cells in ASIC or FPGA designs */ |
`include "pci_constants.v" |
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_pciw_fifo_control |
( |
rclock_in, |
wclock_in, |
renable_in, |
wenable_in, |
reset_in, |
almost_full_out, |
full_out, |
almost_empty_out, |
empty_out, |
waddr_out, |
raddr_out, |
rallow_out, |
wallow_out, |
three_left_out, |
two_left_out |
); |
|
parameter ADDR_LENGTH = 7 ; |
|
// independent clock inputs - rclock_in = read clock, wclock_in = write clock |
input rclock_in, wclock_in; |
|
// enable inputs - read address changes on rising edge of rclock_in when reads are allowed |
// write address changes on rising edge of wclock_in when writes are allowed |
input renable_in, wenable_in; |
|
// reset input |
input reset_in; |
|
// almost full and empy status outputs |
output almost_full_out, almost_empty_out; |
|
// full and empty status outputs |
output full_out, empty_out; |
|
// read and write addresses outputs |
output [(ADDR_LENGTH - 1):0] waddr_out, raddr_out; |
|
// read and write allow outputs |
output rallow_out, wallow_out ; |
|
// three and two locations left output indicator |
output three_left_out ; |
output two_left_out ; |
|
// read address register |
reg [(ADDR_LENGTH - 1):0] raddr ; |
|
// write address register |
reg [(ADDR_LENGTH - 1):0] waddr; |
reg [(ADDR_LENGTH - 1):0] waddr_plus1; |
assign waddr_out = waddr ; |
|
// grey code registers |
// grey code pipeline for write address |
reg [(ADDR_LENGTH - 1):0] wgrey_minus1 ; // previous |
reg [(ADDR_LENGTH - 1):0] wgrey_addr ; // current |
reg [(ADDR_LENGTH - 1):0] wgrey_next ; // next |
|
reg [(ADDR_LENGTH - 1):0] wgrey_next_plus1 ; // next plus 1 |
|
|
// next write gray address calculation - bitwise xor between address and shifted address |
wire [(ADDR_LENGTH - 2):0] calc_wgrey_next = waddr[(ADDR_LENGTH - 1):1] ^ waddr[(ADDR_LENGTH - 2):0] ; |
wire [(ADDR_LENGTH - 2):0] calc_wgrey_next_plus1 = waddr_plus1[(ADDR_LENGTH - 1):1] ^ waddr_plus1[(ADDR_LENGTH - 2):0] ; |
|
// grey code pipeline for read address |
reg [(ADDR_LENGTH - 1):0] rgrey_minus2 ; // two before current |
reg [(ADDR_LENGTH - 1):0] rgrey_minus1 ; // one before current |
reg [(ADDR_LENGTH - 1):0] rgrey_addr ; // current |
reg [(ADDR_LENGTH - 1):0] rgrey_next ; // next |
|
// next read gray address calculation - bitwise xor between address and shifted address |
wire [(ADDR_LENGTH - 2):0] calc_rgrey_next = raddr[(ADDR_LENGTH - 1):1] ^ raddr[(ADDR_LENGTH - 2):0] ; |
|
// write allow - writes are allowed when fifo is not full |
assign wallow_out = wenable_in & ~full_out ; |
|
// clear generation for FFs and registers |
wire clear = reset_in ; |
|
//rallow generation |
assign rallow_out = renable_in & ~empty_out ; // reads allowed if read enable is high and FIFO is not empty |
|
// at any clock edge that rallow is high, this register provides next read address, so wait cycles are not necessary |
// when FIFO is empty, this register provides actual read address, so first location can be read |
reg [(ADDR_LENGTH - 1):0] raddr_plus_one ; |
|
|
// read address mux - when read is performed, next address is driven, so next data is available immediately after read |
// this is convenient for zero wait stait bursts |
assign raddr_out = rallow_out ? raddr_plus_one : raddr ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial values seem a bit odd - they are this way to allow easier grey pipeline implementation and to allow min fifo size of 8 |
raddr_plus_one <= #`FF_DELAY 5 ; |
raddr <= #`FF_DELAY 4 ; |
// raddr_plus_one <= #`FF_DELAY 6 ; |
// raddr <= #`FF_DELAY 5 ; |
end |
else if (rallow_out) |
begin |
raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ; |
raddr <= #`FF_DELAY raddr_plus_one ; |
end |
end |
|
/*----------------------------------------------------------------------------------------------- |
Read address control consists of Read address counter and Grey Address pipeline |
There are 4 Grey addresses: |
- rgrey_minus2 is Grey Code of address two before current address |
- rgrey_minus1 is Grey Code of address one before current address |
- rgrey_addr is Grey Code of current read address |
- rgrey_next is Grey Code of next read address |
--------------------------------------------------------------------------------------------------*/ |
// grey coded address pipeline for status generation in read clock domain |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
rgrey_minus2 <= #1 0 ; |
rgrey_minus1 <= #`FF_DELAY 1 ; |
rgrey_addr <= #1 3 ; |
rgrey_next <= #`FF_DELAY 2 ; |
end |
else |
if (rallow_out) |
begin |
rgrey_minus2 <= #1 rgrey_minus1 ; |
rgrey_minus1 <= #`FF_DELAY rgrey_addr ; |
rgrey_addr <= #1 rgrey_next ; |
rgrey_next <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ; |
end |
end |
|
/*-------------------------------------------------------------------------------------------- |
Write address control consists of write address counter and 3 Grey Code Registers: |
- wgrey_minus1 represents previous Grey coded write address |
- wgrey_addr represents current Grey Coded write address |
- wgrey_next represents next Grey Coded write address |
|
- wgrey_next_plus1 represents second next Grey Coded write address |
|
----------------------------------------------------------------------------------------------*/ |
// grey coded address pipeline for status generation in write clock domain |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
wgrey_minus1 <= #`FF_DELAY 1 ; |
wgrey_addr <= #`FF_DELAY 3 ; |
wgrey_next <= #`FF_DELAY 2 ; |
|
wgrey_next_plus1 <= #`FF_DELAY 6; |
|
end |
else |
if (wallow_out) |
begin |
wgrey_minus1 <= #`FF_DELAY wgrey_addr ; |
wgrey_addr <= #`FF_DELAY wgrey_next ; |
|
wgrey_next <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ; |
// wgrey_next <= #`FF_DELAY wgrey_next_plus1 ; |
wgrey_next_plus1 <= #`FF_DELAY {waddr_plus1[(ADDR_LENGTH - 1)], calc_wgrey_next_plus1} ; |
|
end |
end |
|
// write address counter - nothing special except initial value |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value 5 |
|
waddr <= #`FF_DELAY 4 ; |
waddr_plus1 <= #`FF_DELAY 5 ; |
end |
else |
if (wallow_out) |
begin |
waddr <= #`FF_DELAY waddr + 1'b1 ; |
waddr_plus1 <= #`FF_DELAY waddr_plus1 + 1'b1 ; |
end |
end |
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Gray coded address of read address decremented by two is synchronized to write clock domain and compared to: |
- previous grey coded write address - if they are equal, the fifo is full |
|
- gray coded write address. If they are equal, fifo is almost full. |
|
- grey coded next write address. If they are equal, the fifo has two free locations left. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_minus2 ; |
reg [(ADDR_LENGTH - 1):0] wclk_rgrey_minus2 ; |
|
pci_synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_rgrey_minus2 |
( |
.data_in (rgrey_minus2), |
.clk_out (wclock_in), |
.sync_data_out (wclk_sync_rgrey_minus2), |
.async_reset (clear) |
) ; |
|
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
wclk_rgrey_minus2 <= #`FF_DELAY 0 ; |
end |
else |
begin |
wclk_rgrey_minus2 <= #`FF_DELAY wclk_sync_rgrey_minus2 ; |
end |
end |
|
assign full_out = (wgrey_minus1 == wclk_rgrey_minus2) ; |
assign almost_full_out = (wgrey_addr == wclk_rgrey_minus2) ; |
assign two_left_out = (wgrey_next == wclk_rgrey_minus2) ; |
|
assign three_left_out = (wgrey_next_plus1 == wclk_rgrey_minus2) ; |
|
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Empty control: |
Gray coded write address pointer is synchronized to read clock domain and compared to Gray coded read address pointer. |
If they are equal, fifo is empty. |
|
Almost empty control: |
Synchronized write pointer is also compared to Gray coded next read address. If these two are |
equal, fifo is almost empty. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
wire [(ADDR_LENGTH - 1):0] rclk_sync_wgrey_addr ; |
reg [(ADDR_LENGTH - 1):0] rclk_wgrey_addr ; |
pci_synchronizer_flop #(ADDR_LENGTH, 3) i_synchronizer_reg_wgrey_addr |
( |
.data_in (wgrey_addr), |
.clk_out (rclock_in), |
.sync_data_out (rclk_sync_wgrey_addr), |
.async_reset (clear) |
) ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
rclk_wgrey_addr <= #`FF_DELAY 3 ; |
else |
rclk_wgrey_addr <= #`FF_DELAY rclk_sync_wgrey_addr ; |
end |
|
assign almost_empty_out = (rgrey_next == rclk_wgrey_addr) ; |
assign empty_out = (rgrey_addr == rclk_wgrey_addr) ; |
endmodule |
/verilog/pci_wbs_wbb3_2_wbb2.v
0,0 → 1,250
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pci_wbs_wbb3_2_wbb2.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2003 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// |
|
module pci_wbs_wbb3_2_wbb2 |
( |
wb_clk_i, |
wb_rst_i, |
|
wbs_cyc_i, |
wbs_cyc_o, |
wbs_stb_i, |
wbs_stb_o, |
wbs_adr_i, |
wbs_adr_o, |
wbs_dat_i_i, |
wbs_dat_i_o, |
wbs_dat_o_i, |
wbs_dat_o_o, |
wbs_we_i, |
wbs_we_o, |
wbs_sel_i, |
wbs_sel_o, |
wbs_ack_i, |
wbs_ack_o, |
wbs_err_i, |
wbs_err_o, |
wbs_rty_i, |
wbs_rty_o, |
wbs_cti_i, |
wbs_bte_i, |
wbs_cab_o |
) ; |
|
input wb_clk_i ; |
input wb_rst_i ; |
|
input wbs_cyc_i ; |
output wbs_cyc_o ; |
input wbs_stb_i ; |
output wbs_stb_o ; |
input [31:0] wbs_adr_i ; |
output [31:0] wbs_adr_o ; |
input [31:0] wbs_dat_i_i ; |
output [31:0] wbs_dat_i_o ; |
input [31:0] wbs_dat_o_i ; |
output [31:0] wbs_dat_o_o ; |
input wbs_we_i ; |
output wbs_we_o ; |
input [ 3:0] wbs_sel_i ; |
output [ 3:0] wbs_sel_o ; |
input wbs_ack_i ; |
output wbs_ack_o ; |
input wbs_err_i ; |
output wbs_err_o ; |
input wbs_rty_i ; |
output wbs_rty_o ; |
input [ 2:0] wbs_cti_i ; |
input [ 1:0] wbs_bte_i ; |
output wbs_cab_o ; |
|
reg wbs_cyc_o ; |
reg [31:0] wbs_adr_o ; |
reg [31:0] wbs_dat_i_o ; |
reg wbs_dat_i_o_valid ; |
reg [31:0] wbs_dat_o_o ; |
reg wbs_we_o ; |
reg [ 3:0] wbs_sel_o ; |
reg wbs_ack_o ; |
reg wbs_err_o ; |
reg wbs_rty_o ; |
reg wbs_cab_o ; |
|
always@(posedge wb_rst_i or posedge wb_clk_i) |
begin |
if (wb_rst_i) |
begin |
wbs_cyc_o <= 1'b0 ; |
wbs_adr_o <= 32'h0 ; |
wbs_dat_i_o <= 32'h0 ; |
wbs_dat_o_o <= 32'h0 ; |
wbs_sel_o <= 4'h0 ; |
wbs_we_o <= 1'b0 ; |
wbs_dat_i_o_valid <= 1'b0 ; |
end |
else |
begin:transfer_and_transfer_adr_ctrl_blk |
reg start_cycle ; |
reg [3:0] end_cycle ; |
reg generate_int_adr ; |
|
start_cycle = ~wbs_cyc_o & wbs_cyc_i & wbs_stb_i & ~wbs_ack_o & ~wbs_err_o & ~wbs_rty_o ; |
|
// there is a few conditions when cycle must be terminated |
// I've put them into bit array for better readability of the code |
|
// 1st condition - pci bridge is signaling an error |
end_cycle[0] = wbs_err_i ; |
|
// 2nd condition - pci bridge is signaling a retry - that can be ignored via the defines |
end_cycle[1] = wbs_rty_i `ifdef PCI_WBS_B3_RTY_DISABLE & 1'b0 `endif ; |
|
// 3rd condition - end non burst cycles as soon as pci bridge response is received |
end_cycle[2] = wbs_cyc_i & wbs_stb_i & wbs_ack_i & ~wbs_cab_o ; |
|
// 4th condition - end cycle when acknowledge and strobe are both asserted and master is signaling end of burst |
end_cycle[3] = wbs_cyc_i & wbs_stb_i & wbs_ack_o & wbs_cab_o & (wbs_cti_i == 3'b111) ; |
|
if (wbs_dat_i_o_valid) |
begin |
if (wbs_ack_i | wbs_err_i `ifdef PCI_WBS_B3_RTY_DISABLE `else | wbs_rty_i `endif) |
wbs_dat_i_o_valid <= 1'b0 ; |
end |
else |
begin |
if (wbs_cyc_i & wbs_stb_i & wbs_we_i & ~wbs_ack_o & ~wbs_err_o & ~wbs_rty_o) |
begin |
wbs_dat_i_o <= wbs_dat_i_i ; |
wbs_dat_i_o_valid <= 1'b1 ; |
end |
end |
|
if (start_cycle) |
begin |
wbs_cyc_o <= 1'b1 ; |
wbs_sel_o <= wbs_sel_i ; |
wbs_we_o <= wbs_we_i ; |
|
if (wbs_cti_i == 3'b010) |
begin |
case (wbs_bte_i) |
2'b00: begin |
wbs_cab_o <= 1'b1 ; |
end |
2'b01: begin |
if (wbs_adr_i[3:0] == 4'b0000) |
wbs_cab_o <= 1'b1 ; |
else |
wbs_cab_o <= 1'b0 ; |
end |
2'b10: begin |
if (wbs_adr_i[4:0] == 5'b00000) |
wbs_cab_o <= 1'b1 ; |
else |
wbs_cab_o <= 1'b0 ; |
end |
2'b11: begin |
if (wbs_adr_i[5:0] == 6'b000000) |
wbs_cab_o <= 1'b1 ; |
else |
wbs_cab_o <= 1'b0 ; |
end |
endcase |
end |
else |
begin |
wbs_cab_o <= 1'b0 ; |
end |
end |
else if ( wbs_cyc_o & (|end_cycle) ) |
begin |
wbs_cyc_o <= 1'b0 ; |
end |
|
if (start_cycle) |
wbs_adr_o <= wbs_adr_i ; |
else if (wbs_ack_i) |
wbs_adr_o[31:2] <= wbs_adr_o[31:2] + 1'b1 ; |
|
if (~wbs_we_o & wbs_ack_i) |
wbs_dat_o_o <= wbs_dat_o_i ; |
end |
end |
|
always@(posedge wb_rst_i or posedge wb_clk_i) |
begin |
if (wb_rst_i) |
begin |
wbs_ack_o <= 1'b0 ; |
wbs_err_o <= 1'b0 ; |
wbs_rty_o <= 1'b0 ; |
end |
else |
begin |
if (wbs_ack_o) |
wbs_ack_o <= wbs_ack_i | ~wbs_stb_i ; |
else |
wbs_ack_o <= wbs_ack_i ; |
|
if (wbs_err_o) |
wbs_err_o <= ~wbs_stb_i ; |
else |
wbs_err_o <= wbs_err_i ; |
|
`ifdef PCI_WBS_B3_RTY_DISABLE |
wbs_rty_o <= 1'b0 ; |
`else |
if (wbs_rty_o) |
wbs_rty_o <= ~wbs_stb_i ; |
else |
wbs_rty_o <= wbs_rty_i ; |
`endif |
end |
end |
|
assign wbs_stb_o = (wbs_cyc_o & ~wbs_we_o & ~wbs_ack_o & ~wbs_err_o & ~wbs_rty_o) | |
(wbs_cyc_o & wbs_stb_i & wbs_cab_o & ~wbs_we_o & wbs_cti_i !== 3'b111) | |
(wbs_cyc_o & wbs_we_o & wbs_dat_i_o_valid) ; |
|
endmodule |
/verilog/pci_target32_sm.v
0,0 → 1,755
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_target32_sm.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.9 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.8 2003/01/21 16:06:56 mihad |
// Bug fixes, testcases added. |
// |
// Revision 1.7 2002/09/24 19:09:17 mihad |
// Number of state bits define was removed |
// |
// Revision 1.6 2002/09/24 18:30:00 mihad |
// Changed state machine encoding to true one-hot |
// |
// Revision 1.5 2002/08/22 09:07:06 mihad |
// Fixed a bug and provided testcase for it. Target was responding to configuration cycle type 1 transactions. |
// |
// Revision 1.4 2002/02/19 16:32:37 mihad |
// Modified testbench and fixed some bugs |
// |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_target32_sm |
( |
// system inputs |
clk_in, |
reset_in, |
// master inputs |
pci_frame_in, |
pci_irdy_in, |
pci_idsel_in, |
pci_frame_reg_in, |
pci_irdy_reg_in, |
pci_idsel_reg_in, |
// target response outputs |
pci_trdy_out, |
pci_stop_out, |
pci_devsel_out, |
pci_trdy_en_out, |
pci_stop_en_out, |
pci_devsel_en_out, |
ad_load_out, |
ad_load_on_transfer_out, |
// address, data, bus command, byte enable in/outs |
pci_ad_reg_in, |
pci_ad_out, |
pci_ad_en_out, |
pci_cbe_reg_in, |
pci_cbe_in, |
bckp_trdy_en_in, |
bckp_devsel_in, |
bckp_trdy_in, |
bckp_stop_in, |
pci_trdy_reg_in, |
pci_stop_reg_in, |
|
// backend side of state machine with control signals to pci_io_mux ... |
address_out, |
addr_claim_in, |
bc_out, |
bc0_out, |
data_out, |
data_in, |
be_out, |
next_be_out, |
req_out, |
rdy_out, |
addr_phase_out, |
bckp_devsel_out, |
bckp_trdy_out, |
bckp_stop_out, |
last_reg_out, |
frame_reg_out, |
fetch_pcir_fifo_out, |
load_medium_reg_out, |
sel_fifo_mreg_out, |
sel_conf_fifo_out, |
fetch_conf_out, |
load_to_pciw_fifo_out, |
load_to_conf_out, |
same_read_in, |
norm_access_to_config_in, |
read_completed_in, |
read_processing_in, |
target_abort_in, |
disconect_wo_data_in, |
disconect_w_data_in, |
target_abort_set_out, |
pciw_fifo_full_in, |
pcir_fifo_data_err_in, |
wbw_fifo_empty_in, |
wbu_del_read_comp_pending_in, |
wbu_frame_en_in |
|
) ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Various parameters needed for state machine and other stuff |
----------------------------------------------------------------------------------------------------------------------*/ |
parameter S_IDLE = 3'b001 ; |
parameter S_WAIT = 3'b010 ; |
parameter S_TRANSFERE = 3'b100 ; |
|
|
/*================================================================================================================== |
System inputs. |
==================================================================================================================*/ |
// PCI side clock and reset |
input clk_in, |
reset_in ; |
|
|
/*================================================================================================================== |
PCI interface signals - bidirectional signals are divided to inputs and outputs in I/O cells instantiation |
module. Enables are separate signals. |
==================================================================================================================*/ |
// master inputs |
input pci_frame_in, |
pci_irdy_in, |
pci_idsel_in ; |
input pci_frame_reg_in, |
pci_irdy_reg_in, |
pci_idsel_reg_in ; |
|
// target response outputs |
output pci_trdy_out, |
pci_stop_out, |
pci_devsel_out ; |
output pci_trdy_en_out, |
pci_stop_en_out, |
pci_devsel_en_out ; |
output ad_load_out ; |
output ad_load_on_transfer_out ; |
// address, data, bus command, byte enable in/outs |
input [31:0] pci_ad_reg_in ; |
output [31:0] pci_ad_out ; |
output pci_ad_en_out ; |
input [3:0] pci_cbe_reg_in ; |
input [3:0] pci_cbe_in ; |
input bckp_trdy_en_in ; |
input bckp_devsel_in ; |
input bckp_trdy_in ; |
input bckp_stop_in ; |
input pci_trdy_reg_in ; |
input pci_stop_reg_in ; |
|
|
/*================================================================================================================== |
Other side of PCI Target state machine |
==================================================================================================================*/ |
// Data, byte enables, bus commands and address ports |
output [31:0] address_out ; // current request address output - registered |
input addr_claim_in ; // current request address claim input |
output [3:0] bc_out ; // current request bus command output - registered |
output bc0_out ; // current cycle RW signal output |
input [31:0] data_in ; // for read operations - current dataphase data input |
output [31:0] data_out ; // for write operations - current request data output - registered |
output [3:0] be_out ; // current dataphase byte enable outputs - registered |
output [3:0] next_be_out ; // next dataphase byte enable outputs - NOT registered |
// Port connection control signals from PCI FSM |
output req_out ; // Read is requested to WB master |
output rdy_out ; // DATA / ADDRESS selection when read or write - registered |
output addr_phase_out ; // Indicates address phase and also fast-back-to-back address phase - registered |
output bckp_devsel_out ; // DEVSEL output (which is registered) equivalent |
output bckp_trdy_out ; // TRDY output (which is registered) equivalent |
output bckp_stop_out ; // STOP output (which is registered) equivalent |
output last_reg_out ; // Indicates last data phase - registered |
output frame_reg_out ; // FRAME output signal - registered |
output fetch_pcir_fifo_out ;// Read enable for PCIR_FIFO when when read is finishen on WB side |
output load_medium_reg_out ;// Load data from PCIR_FIFO to medium register (first data must be prepared on time) |
output sel_fifo_mreg_out ; // Read data selection between PCIR_FIFO and medium register |
output sel_conf_fifo_out ; // Read data selection between Configuration registers and "FIFO" |
output fetch_conf_out ; // Read enable for configuration space registers |
output load_to_pciw_fifo_out ;// Write enable to PCIW_FIFO |
output load_to_conf_out ; // Write enable to Configuration space registers |
|
|
/*================================================================================================================== |
Status |
==================================================================================================================*/ |
input same_read_in ; // Indicates the same read request (important when read is finished on WB side) |
input norm_access_to_config_in ; // Indicates the access to Configuration space with MEMORY commands |
input read_completed_in ; // Indicates that read request is completed on WB side |
input read_processing_in ; // Indicates that read request is processing on WB side |
input target_abort_in ; // Indicates target abort termination |
input disconect_wo_data_in ; // Indicates disconnect without data termination |
input disconect_w_data_in ; // Indicates disconnect with data termination |
input pciw_fifo_full_in ; // Indicates that write PCIW_FIFO is full |
input pcir_fifo_data_err_in ; // Indicates data error on current data read from PCIR_FIFO |
input wbw_fifo_empty_in ; // Indicates that WB SLAVE UNIT has no data to be written to PCI bus |
|
input wbu_frame_en_in ; // Indicates that WB SLAVE UNIT is accessing the PCI bus (important if |
// address on PCI bus is also claimed by decoder in this PCI TARGET UNIT |
output target_abort_set_out ; // Signal used to be set in configuration space registers |
|
/*================================================================================================================== |
END of input / output PORT DEFINITONS !!! |
==================================================================================================================*/ |
|
// Delayed frame signal for determining the address phase |
reg previous_frame ; |
// Delayed read completed signal for preparing the data from pcir fifo |
reg read_completed_reg ; |
// Delayed disconnect with/without data for stop loading data to PCIW_FIFO |
//reg disconect_wo_data_reg ; |
|
wire config_disconnect ; |
wire disconect_wo_data = disconect_wo_data_in || config_disconnect ; |
wire disconect_w_data = disconect_w_data_in ; |
// Delayed frame signal for determining the address phase! |
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
previous_frame <= #`FF_DELAY 1'b1 ; |
read_completed_reg <= #`FF_DELAY 1'b0 ; |
end |
else |
begin |
previous_frame <= #`FF_DELAY pci_frame_reg_in ; |
read_completed_reg <= #`FF_DELAY read_completed_in ; |
end |
end |
|
// Address phase is when previous frame was 1 and this frame is 0 and frame isn't generated from pci master (in WBU) |
wire addr_phase = (previous_frame && ~pci_frame_reg_in && ~wbu_frame_en_in) ; |
|
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
// Wire tells when there is configuration (read or write) command with IDSEL signal active |
wire config_access = 1'b0 ; |
// Write and read progresses are used for determining next state |
wire write_progress = ( (read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) || |
(~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ) ; |
wire read_progress = ( (read_completed_in && wbw_fifo_empty_in) ) ; |
`else |
// Wire tells when there is configuration (read or write) command with IDSEL signal active |
wire config_access = (pci_idsel_reg_in && pci_cbe_reg_in[3]) && (~pci_cbe_reg_in[2] && pci_cbe_reg_in[1]) && // idsel asserted with correct bus command(101x) |
(pci_ad_reg_in[1:0] == 2'b00) ; // has to be type 0 configuration cycle |
|
// Write and read progresses are used for determining next state |
wire write_progress = ( (norm_access_to_config_in) || |
(read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) || |
(~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ) ; |
wire read_progress = ( (~read_completed_in && norm_access_to_config_in) || |
(read_completed_in && wbw_fifo_empty_in) ) ; |
`endif |
`else |
// Wire tells when there is configuration (read or write) command with IDSEL signal active |
wire config_access = (pci_idsel_reg_in && pci_cbe_reg_in[3]) && (~pci_cbe_reg_in[2] && pci_cbe_reg_in[1]) && // idsel asserted with correct bus command(101x) |
(pci_ad_reg_in[1:0] == 2'b00) ; // has to be type 0 configuration cycle |
|
// Write and read progresses are used for determining next state |
wire write_progress = ( (norm_access_to_config_in) || |
(read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) || |
(~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ) ; |
wire read_progress = ( (~read_completed_in && norm_access_to_config_in) || |
(read_completed_in && wbw_fifo_empty_in) ) ; |
`endif |
|
// Signal for loading data to medium register from pcir fifo when read completed from WB side! |
wire prepare_rd_fifo_data = (read_completed_in && ~read_completed_reg) ; |
|
// Write allowed to PCIW_FIFO |
wire write_to_fifo = ((read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) || |
(~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in)) ; |
// Read allowed from PCIR_FIFO |
wire read_from_fifo = (read_completed_in && wbw_fifo_empty_in) ; |
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
// Read request is allowed to be proceed regarding the WB side |
wire read_request = (~read_completed_in && ~read_processing_in) ; |
`else |
// Read request is allowed to be proceed regarding the WB side |
wire read_request = (~read_completed_in && ~read_processing_in && ~norm_access_to_config_in) ; |
`endif |
`else |
// Read request is allowed to be proceed regarding the WB side |
wire read_request = (~read_completed_in && ~read_processing_in && ~norm_access_to_config_in) ; |
`endif |
|
// Critically calculated signals are latched in this clock period (address phase) to be used in the next clock period |
reg rw_cbe0 ; |
reg wr_progress ; |
reg rd_progress ; |
reg rd_from_fifo ; |
reg rd_request ; |
reg wr_to_fifo ; |
reg same_read_reg ; |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
rw_cbe0 <= #`FF_DELAY 1'b0 ; |
wr_progress <= #`FF_DELAY 1'b0 ; |
rd_progress <= #`FF_DELAY 1'b0 ; |
rd_from_fifo <= #`FF_DELAY 1'b0 ; |
rd_request <= #`FF_DELAY 1'b0 ; |
wr_to_fifo <= #`FF_DELAY 1'b0 ; |
same_read_reg <= #`FF_DELAY 1'b0 ; |
end |
else |
begin |
if (addr_phase) |
begin |
rw_cbe0 <= #`FF_DELAY pci_cbe_reg_in[0] ; |
wr_progress <= #`FF_DELAY write_progress ; |
rd_progress <= #`FF_DELAY read_progress ; |
rd_from_fifo <= #`FF_DELAY read_from_fifo ; |
rd_request <= #`FF_DELAY read_request ; |
wr_to_fifo <= #`FF_DELAY write_to_fifo ; |
same_read_reg <= #`FF_DELAY same_read_in ; |
end |
end |
end |
|
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
wire norm_access_to_conf_reg = 1'b0 ; |
wire cnf_progress = 1'b0 ; |
`else |
reg norm_access_to_conf_reg ; |
reg cnf_progress ; |
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
norm_access_to_conf_reg <= #`FF_DELAY 1'b0 ; |
cnf_progress <= #`FF_DELAY 1'b0 ; |
end |
else |
begin |
if (addr_phase) |
begin |
norm_access_to_conf_reg <= #`FF_DELAY norm_access_to_config_in ; |
cnf_progress <= #`FF_DELAY config_access ; |
end |
end |
end |
`endif |
`else |
reg norm_access_to_conf_reg ; |
reg cnf_progress ; |
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
norm_access_to_conf_reg <= #`FF_DELAY 1'b0 ; |
cnf_progress <= #`FF_DELAY 1'b0 ; |
end |
else |
begin |
if (addr_phase) |
begin |
norm_access_to_conf_reg <= #`FF_DELAY norm_access_to_config_in ; |
cnf_progress <= #`FF_DELAY config_access ; |
end |
end |
end |
`endif |
|
// Signal used in S_WAIT state to determin next state |
wire s_wait_progress = ( |
(~cnf_progress && rw_cbe0 && wr_progress && ~target_abort_in) || |
(~cnf_progress && ~rw_cbe0 && same_read_reg && rd_progress && ~target_abort_in && ~pcir_fifo_data_err_in) || |
(~cnf_progress && ~rw_cbe0 && ~same_read_reg && norm_access_to_conf_reg && ~target_abort_in) || |
(cnf_progress && ~target_abort_in) |
) ; |
|
// Signal used in S_TRANSFERE state to determin next state |
wire s_tran_progress = ( |
(rw_cbe0 && !disconect_wo_data) || |
(~rw_cbe0 && !disconect_wo_data && !target_abort_in && !pcir_fifo_data_err_in) |
) ; |
|
// Clock enable for PCI state machine driven directly from critical inputs - FRAME and IRDY |
wire pcit_sm_clk_en ; |
// FSM states signals indicating the current state |
reg state_idle ; |
reg state_wait ; |
reg sm_transfere ; |
reg backoff ; |
reg state_default ; |
wire state_backoff = sm_transfere && backoff ; |
wire state_transfere = sm_transfere && !backoff ; |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
backoff <= #`FF_DELAY 1'b0 ; |
else if ( state_idle ) |
backoff <= #`FF_DELAY 1'b0 ; |
else |
backoff <= #`FF_DELAY (state_wait && !s_wait_progress) || |
(sm_transfere && !s_tran_progress && !pci_frame_in && !pci_irdy_in) || |
backoff ; |
end |
assign config_disconnect = sm_transfere && (norm_access_to_conf_reg || cnf_progress) ; |
|
// Clock enable module used for preserving the architecture because of minimum delay for critical inputs |
pci_target32_clk_en pci_target_clock_en |
( |
.addr_phase (addr_phase), |
.config_access (config_access), |
.addr_claim_in (addr_claim_in), |
.pci_frame_in (pci_frame_in), |
.state_wait (state_wait), |
.state_transfere (sm_transfere), |
.state_default (state_default), |
.clk_enable (pcit_sm_clk_en) |
); |
|
reg [2:0] c_state ; //current state register |
reg [2:0] n_state ; //next state input to current state register |
|
// state machine register control |
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) // reset state machine to S_IDLE state |
c_state <= #`FF_DELAY S_IDLE ; |
else |
if (pcit_sm_clk_en) // if conditions are true, then FSM goes to next state! |
c_state <= #`FF_DELAY n_state ; |
end |
|
// state machine logic |
always@(c_state) |
begin |
case (c_state) |
S_IDLE : |
begin |
state_idle <= 1'b1 ; |
state_wait <= 1'b0 ; |
sm_transfere <= 1'b0 ; |
state_default <= 1'b0 ; |
n_state <= S_WAIT ; |
end |
S_WAIT : |
begin |
state_idle <= 1'b0 ; |
state_wait <= 1'b1 ; |
sm_transfere <= 1'b0 ; |
state_default <= 1'b0 ; |
n_state <= S_TRANSFERE ; |
end |
S_TRANSFERE : |
begin |
state_idle <= 1'b0 ; |
state_wait <= 1'b0 ; |
sm_transfere <= 1'b1 ; |
state_default <= 1'b0 ; |
n_state <= S_IDLE ; |
end |
default : |
begin |
state_idle <= 1'b0 ; |
state_wait <= 1'b0 ; |
sm_transfere <= 1'b0 ; |
state_default <= 1'b1 ; |
n_state <= S_IDLE ; |
end |
endcase |
end |
|
// if not retry and not target abort |
// NO CRITICAL SIGNALS |
wire trdy_w = ( |
(state_wait && ~cnf_progress && rw_cbe0 && wr_progress && ~target_abort_in) || |
(state_wait && ~cnf_progress && ~rw_cbe0 && same_read_reg && rd_progress && ~target_abort_in && !pcir_fifo_data_err_in) || |
(state_wait && ~cnf_progress && ~rw_cbe0 && ~same_read_reg && norm_access_to_conf_reg && ~target_abort_in) || |
(state_wait && cnf_progress && ~target_abort_in) |
) ; |
// if not disconnect without data and not target abort (only during reads) |
// MUST BE ANDED WITH CRITICAL ~FRAME |
wire trdy_w_frm = ( |
(state_transfere && !cnf_progress && !norm_access_to_conf_reg && rw_cbe0 && !disconect_wo_data) || |
(state_transfere && !cnf_progress && !norm_access_to_conf_reg && ~rw_cbe0 && !disconect_wo_data && ~pcir_fifo_data_err_in) || |
(state_transfere && !cnf_progress && !norm_access_to_conf_reg && disconect_w_data && pci_irdy_reg_in && |
((~rw_cbe0 && ~pcir_fifo_data_err_in) || rw_cbe0)) |
) ; |
// if not disconnect without data and not target abort (only during reads) |
// MUST BE ANDED WITH CRITICAL ~FRAME AND IRDY |
wire trdy_w_frm_irdy = ( ~bckp_trdy_in ) ; |
// TRDY critical module used for preserving the architecture because of minimum delay for critical inputs |
pci_target32_trdy_crit pci_target_trdy_critical |
( |
.trdy_w (trdy_w), |
.trdy_w_frm (trdy_w_frm), |
.trdy_w_frm_irdy (trdy_w_frm_irdy), |
.pci_frame_in (pci_frame_in), |
.pci_irdy_in (pci_irdy_in), |
.pci_trdy_out (pci_trdy_out) |
); |
|
// if target abort or retry |
// NO CRITICAL SIGNALS |
wire stop_w = ( |
(state_wait && target_abort_in) || |
(state_wait && ~cnf_progress && rw_cbe0 && ~wr_progress) || |
(state_wait && ~cnf_progress && ~rw_cbe0 && same_read_reg && ~rd_progress) || |
(state_wait && ~cnf_progress && ~rw_cbe0 && same_read_reg && rd_progress && pcir_fifo_data_err_in) || |
(state_wait && ~cnf_progress && ~rw_cbe0 && ~same_read_reg && ~norm_access_to_conf_reg) |
) ; |
// if asserted, wait for deactivating the frame |
// MUST BE ANDED WITH CRITICAL ~FRAME |
wire stop_w_frm = ( |
(state_backoff && ~bckp_stop_in) |
) ; |
// if target abort or if disconnect without data (after data transfere) |
// MUST BE ANDED WITH CRITICAL ~FRAME AND ~IRDY |
wire stop_w_frm_irdy = ( |
(state_transfere && (disconect_wo_data)) || |
(state_transfere && ~rw_cbe0 && pcir_fifo_data_err_in) |
) ; |
// STOP critical module used for preserving the architecture because of minimum delay for critical inputs |
pci_target32_stop_crit pci_target_stop_critical |
( |
.stop_w (stop_w), |
.stop_w_frm (stop_w_frm), |
.stop_w_frm_irdy (stop_w_frm_irdy), |
.pci_frame_in (pci_frame_in), |
.pci_irdy_in (pci_irdy_in), |
.pci_stop_out (pci_stop_out) |
); |
|
// if OK to respond and not target abort |
// NO CRITICAL SIGNALS |
wire devs_w = ( |
(addr_phase && config_access) || |
(addr_phase && ~config_access && addr_claim_in) || |
(state_wait && ~target_abort_in && !(~cnf_progress && ~rw_cbe0 && same_read_reg && rd_progress && pcir_fifo_data_err_in) ) |
) ; |
|
// if not target abort (only during reads) or if asserted, wait for deactivating the frame |
// MUST BE ANDED WITH CRITICAL ~FRAME |
wire devs_w_frm = ( |
(state_transfere && rw_cbe0) || |
(state_transfere && ~rw_cbe0 && ~pcir_fifo_data_err_in) || |
(state_backoff && ~bckp_devsel_in) |
) ; |
// if not target abort (only during reads) |
// MUST BE ANDED WITH CRITICAL ~FRAME AND IRDY |
wire devs_w_frm_irdy = ( |
(state_transfere && ~rw_cbe0 && pcir_fifo_data_err_in) |
) ; |
// DEVSEL critical module used for preserving the architecture because of minimum delay for critical inputs |
pci_target32_devs_crit pci_target_devsel_critical |
( |
.devs_w (devs_w), |
.devs_w_frm (devs_w_frm), |
.devs_w_frm_irdy (devs_w_frm_irdy), |
.pci_frame_in (pci_frame_in), |
.pci_irdy_in (pci_irdy_in), |
.pci_devsel_out (pci_devsel_out) |
); |
|
// signal used in AD enable module with preserving the hierarchy because of minimum delay for critical inputs |
assign pci_ad_en_out = ( |
(addr_phase && config_access && ~pci_cbe_reg_in[0]) || |
(addr_phase && ~config_access && addr_claim_in && ~pci_cbe_reg_in[0]) || |
(state_wait && ~rw_cbe0) || |
(state_transfere && ~rw_cbe0) || |
(state_backoff && ~rw_cbe0 && ~pci_frame_reg_in) |
) ; |
|
wire fast_back_to_back = (addr_phase && ~pci_irdy_reg_in) ; |
|
// if cycle will progress or will not be stopped |
// NO CRITICAL SIGNALS |
wire ctrl_en = |
/*(~wbu_frame_en_in && fast_back_to_back) ||*/ |
(addr_phase && config_access) || |
(addr_phase && ~config_access && addr_claim_in) || |
(state_wait) || |
(state_transfere && ~(pci_frame_reg_in && ~pci_irdy_reg_in && (~pci_stop_reg_in || ~pci_trdy_reg_in))) || |
(state_backoff && ~(pci_frame_reg_in && ~pci_irdy_reg_in && (~pci_stop_reg_in || ~pci_trdy_reg_in))) ; |
|
assign pci_trdy_en_out = ctrl_en ; |
assign pci_stop_en_out = ctrl_en ; |
assign pci_devsel_en_out = ctrl_en ; |
|
// target ready output signal delayed for one clock used in conjunction with irdy_reg to select which |
// data are registered in io mux module - from fifo or medoum register |
reg bckp_trdy_reg ; |
// delayed indicators for states transfere and backoff |
reg state_transfere_reg ; |
reg state_backoff_reg ; |
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
bckp_trdy_reg <= #`FF_DELAY 1'b1 ; |
state_transfere_reg <= #`FF_DELAY 1'b0 ; |
state_backoff_reg <= #`FF_DELAY 1'b0 ; |
end |
else |
begin |
bckp_trdy_reg <= #`FF_DELAY bckp_trdy_in ; |
state_transfere_reg <= #`FF_DELAY state_transfere ; |
state_backoff_reg <= #`FF_DELAY state_backoff ; |
end |
end |
|
// Read control signals assignments |
assign |
fetch_pcir_fifo_out = ( |
(prepare_rd_fifo_data) || |
(state_wait && ~cnf_progress && ~rw_cbe0 && same_read_reg && rd_from_fifo && ~target_abort_in) || |
(bckp_trdy_en_in && ~pci_trdy_reg_in && ~cnf_progress && ~rw_cbe0 && same_read_reg && rd_from_fifo && ~pci_irdy_reg_in) |
) ; |
|
assign ad_load_out = (state_wait) ; |
|
assign ad_load_on_transfer_out = (bckp_trdy_en_in && ~rw_cbe0) ; |
|
assign load_medium_reg_out = ( |
(prepare_rd_fifo_data) || |
(state_wait && ~rw_cbe0 && ~cnf_progress && same_read_reg && rd_from_fifo && ~target_abort_in) || |
(~pci_irdy_reg_in && ~rw_cbe0 && ~cnf_progress && same_read_reg && rd_from_fifo && ~pci_trdy_reg_in && bckp_trdy_en_in) |
) ; |
|
assign sel_fifo_mreg_out = (~pci_irdy_reg_in && ~bckp_trdy_reg) ; |
|
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
assign sel_conf_fifo_out = 1'b0 ; |
`else |
assign sel_conf_fifo_out = (cnf_progress || norm_access_to_conf_reg) ; |
`endif |
`else |
assign sel_conf_fifo_out = (cnf_progress || norm_access_to_conf_reg) ; |
`endif |
|
// NOT USED NOW, SINCE READ IS ASYNCHRONOUS |
//assign fetch_conf_out = ((cnf_progress || norm_access_to_conf_reg) && ~rw_cbe0 && ~bckp_devsel_in) ; |
assign fetch_conf_out = 1'b0 ; |
|
// Write control signals assignments |
assign |
load_to_pciw_fifo_out = ( |
(state_wait && (~cnf_progress && ~norm_access_to_conf_reg) && rw_cbe0 && wr_to_fifo && ~target_abort_in) || |
(state_transfere_reg && ~state_backoff && rw_cbe0 && wr_to_fifo /*&& ~disconect_wo_data_reg*/ && ~pci_irdy_reg_in && ~bckp_trdy_reg && (~cnf_progress && ~norm_access_to_conf_reg)) || |
((state_backoff || state_backoff_reg) && rw_cbe0 && wr_to_fifo && ~pci_irdy_reg_in && ~bckp_trdy_reg && (~cnf_progress && ~norm_access_to_conf_reg)) |
) ; |
|
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
assign load_to_conf_out = 1'b0 ; |
`else |
assign load_to_conf_out = ( |
(state_transfere_reg && cnf_progress && rw_cbe0 && ~pci_irdy_reg_in && ~bckp_trdy_reg) || |
(state_transfere_reg && norm_access_to_conf_reg && rw_cbe0 && ~pci_irdy_reg_in && ~bckp_trdy_reg) |
) ; |
`endif |
`else |
assign load_to_conf_out = ( |
(state_transfere_reg && cnf_progress && rw_cbe0 && ~pci_irdy_reg_in && ~bckp_trdy_reg) || |
(state_transfere_reg && norm_access_to_conf_reg && rw_cbe0 && ~pci_irdy_reg_in && ~bckp_trdy_reg) |
) ; |
`endif |
|
// General control sigal assignments |
assign addr_phase_out = addr_phase ; |
assign last_reg_out = (pci_frame_reg_in && ~pci_irdy_reg_in) ; |
assign frame_reg_out = pci_frame_reg_in ; |
assign bckp_devsel_out = bckp_devsel_in ; |
assign bckp_trdy_out = bckp_trdy_in ; |
assign bckp_stop_out = bckp_stop_in ; |
assign target_abort_set_out = (bckp_devsel_in && bckp_trdy_in && ~bckp_stop_in && bckp_trdy_en_in) ; |
// request signal for delayed sinc. module |
reg master_will_request_read ; |
always@(posedge clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
master_will_request_read <= #`FF_DELAY 1'b0 ; |
else |
master_will_request_read <= #`FF_DELAY ((state_wait && ~target_abort_in) || (state_backoff && ~target_abort_set_out)) && ~cnf_progress && ~norm_access_to_conf_reg && ~rw_cbe0 && rd_request ; |
end |
// MORE OPTIMIZED READS, but not easy to control in a testbench! |
//assign req_out = master_will_request_read ; |
assign req_out = master_will_request_read && !pci_irdy_reg_in && !read_processing_in ; |
|
// ready tells when address or data are written into fifo - RDY ? DATA : ADDRESS |
assign rdy_out = ~bckp_trdy_reg ; |
|
// data and address outputs assignments! |
assign pci_ad_out = data_in ; |
|
assign data_out = pci_ad_reg_in ; |
assign be_out = pci_cbe_reg_in ; |
assign next_be_out = pci_cbe_in ; |
assign address_out = pci_ad_reg_in ; |
assign bc_out = pci_cbe_reg_in ; |
assign bc0_out = rw_cbe0 ; |
|
|
endmodule |
/verilog/pci_user_constants.v
0,0 → 1,243
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pci_user_constants.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// - Tadej Markovic (tadej@opencores.org) //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.8 2003/03/14 15:31:57 mihad |
// Entered the option to disable no response counter in wb master. |
// |
// Revision 1.7 2003/01/27 17:05:50 mihad |
// Updated. |
// |
// Revision 1.6 2003/01/27 16:51:19 mihad |
// Old files with wrong names removed. |
// |
// Revision 1.5 2003/01/21 16:06:56 mihad |
// Bug fixes, testcases added. |
// |
// Revision 1.4 2002/09/30 17:22:45 mihad |
// Added support for Virtual Silicon two port RAM. Didn't run regression on it yet! |
// |
// Revision 1.3 2002/08/13 11:03:53 mihad |
// Added a few testcases. Repaired wrong reset value for PCI_AM5 register. Repaired Parity Error Detected bit setting. Changed PCI_AM0 to always enabled(regardles of PCI_AM0 define), if image 0 is used as configuration image |
// |
// Revision 1.2 2002/03/05 11:53:47 mihad |
// Added some testcases, removed un-needed fifo signals |
// |
// Revision 1.1 2002/02/01 14:43:31 mihad |
// *** empty log message *** |
// |
// |
|
// Fifo implementation defines: |
// If FPGA and XILINX are defined, Xilinx's BlockSelectRAM+ is instantiated for Fifo storage. |
// 16 bit width is used, so 8 bits of address ( 256 ) locations are available. If RAM_DONT_SHARE is not defined (commented out), |
// then one block RAM is shared between two FIFOs. That means each Fifo can have a maximum address length of 7 - depth of 128 and only 6 block rams are used |
// If RAM_DONT_SHARE is defined ( not commented out ), then 12 block RAMs are used and each Fifo can have a maximum address length of 8 ( 256 locations ) |
// If FPGA is not defined, then ASIC RAMs are used. Currently there is only one version of ARTISAN RAM supported. User should generate synchronous RAM with |
// width of 40 and instantiate it in pci_tpram.v. If RAM_DONT_SHARE is defined, then these can be dual port rams ( write port |
// in one clock domain, read in other ), otherwise it must be two port RAM ( read and write ports in both clock domains ). |
// If RAM_DONT_SHARE is defined, then all RAM address lengths must be specified accordingly, otherwise there are two relevant lengths - PCI_FIFO_RAM_ADDR_LENGTH and |
// WB_FIFO_RAM_ADDR_LENGTH. |
|
`define WBW_ADDR_LENGTH 3 |
`define WBR_ADDR_LENGTH 5 |
`define PCIW_ADDR_LENGTH 3 |
`define PCIR_ADDR_LENGTH 3 |
|
`define FPGA |
`define XILINX |
|
//`define WB_RAM_DONT_SHARE |
`define PCI_RAM_DONT_SHARE |
|
`ifdef FPGA |
`ifdef XILINX |
`define PCI_FIFO_RAM_ADDR_LENGTH 4 // PCI target unit fifo storage definition |
`define WB_FIFO_RAM_ADDR_LENGTH 8 // WB slave unit fifo storage definition |
//`define PCI_XILINX_RAMB4 |
`define WB_XILINX_RAMB4 |
`define PCI_XILINX_DIST_RAM |
//`define WB_XILINX_DIST_RAM |
`endif |
`else |
`define PCI_FIFO_RAM_ADDR_LENGTH 4 // PCI target unit fifo storage definition when RAM sharing is used ( both pcir and pciw fifo use same instance of RAM ) |
`define WB_FIFO_RAM_ADDR_LENGTH 7 // WB slave unit fifo storage definition when RAM sharing is used ( both wbr and wbw fifo use same instance of RAM ) |
// `define WB_ARTISAN_SDP |
// `define PCI_ARTISAN_SDP |
// `define PCI_VS_STP |
// `define WB_VS_STP |
`endif |
|
// these two defines allow user to select active high or low output enables on PCI bus signals, depending on |
// output buffers instantiated. Xilinx FPGAs use active low output enables. |
`define ACTIVE_LOW_OE |
//`define ACTIVE_HIGH_OE |
|
// HOST/GUEST implementation selection - see design document and specification for description of each implementation |
// only one can be defined at same time |
//`define HOST |
`define GUEST |
|
// if NO_CNF_IMAGE is commented out, then READ-ONLY access to configuration space is ENABLED: |
// - ENABLED Read-Only access from WISHBONE for GUEST bridges |
// - ENABLED Read-Only access from PCI for HOST bridges |
// with defining NO_CNF_IMAGE, one decoder and one multiplexer are saved |
`define NO_CNF_IMAGE |
|
// number defined here specifies how many MS bits in PCI address are compared with base address, to decode |
// accesses. Maximum number allows for minimum image size ( number = 20, image size = 4KB ), minimum number |
// allows for maximum image size ( number = 1, image size = 2GB ). If you intend on using different sizes of PCI images, |
// you have to define a number of minimum sized image and enlarge others by specifying different address mask. |
// smaller the number here, faster the decoder operation |
`define PCI_NUM_OF_DEC_ADDR_LINES 12 |
|
// no. of PCI Target IMAGES |
// - PCI provides 6 base address registers for image implementation. |
// PCI_IMAGE1 definition is not required and has no effect, since PCI image 1 is always implemented |
// If GUEST is defined, PCI Image 0 is also always implemented and is used for configuration space |
// access. |
// If HOST is defined and NO_CNF_IMAGE is not, then PCI Image 0 is used for Read Only access to configuration |
// space. If HOST is defined and NO_CNF_IMAGE is defined, then user can define PCI_IMAGE0 as normal image, and there |
// is no access to Configuration space possible from PCI bus. |
// Implementation of all other PCI images is selected by defining PCI_IMAGE2 through PCI_IMAGE5 regardles of HOST |
// or GUEST implementation. |
`ifdef HOST |
`ifdef NO_CNF_IMAGE |
`define PCI_IMAGE0 |
`endif |
`endif |
|
//`define PCI_IMAGE2 |
//`define PCI_IMAGE3 |
//`define PCI_IMAGE4 |
//`define PCI_IMAGE5 |
|
// initial value for PCI image address masks. Address masks can be defined in enabled state, |
// to allow device independent software to detect size of image and map base addresses to |
// memory space. If initial mask for an image is defined as 0, then device independent software |
// won't detect base address implemented and device dependent software will have to configure |
// address masks as well as base addresses! |
`define PCI_AM0 20'hffff_f |
`define PCI_AM1 20'hffff_f |
`define PCI_AM2 20'hffff_8 |
`define PCI_AM3 20'hffff_0 |
`define PCI_AM4 20'hfffe_0 |
`define PCI_AM5 20'h0000_0 |
|
// initial value for PCI image maping to MEMORY or IO spaces. If initial define is set to 0, |
// then IMAGE with that base address points to MEMORY space, othervise it points ti IO space. D |
// Device independent software sets the base addresses acording to MEMORY or IO maping! |
`define PCI_BA0_MEM_IO 1'b0 // considered only when PCI_IMAGE0 is used as general PCI-WB image! |
`define PCI_BA1_MEM_IO 1'b0 |
`define PCI_BA2_MEM_IO 1'b0 |
`define PCI_BA3_MEM_IO 1'b1 |
`define PCI_BA4_MEM_IO 1'b0 |
`define PCI_BA5_MEM_IO 1'b1 |
|
// number defined here specifies how many MS bits in WB address are compared with base address, to decode |
// accesses. Maximum number allows for minimum image size ( number = 20, image size = 4KB ), minimum number |
// allows for maximum image size ( number = 1, image size = 2GB ). If you intend on using different sizes of WB images, |
// you have to define a number of minimum sized image and enlarge others by specifying different address mask. |
// smaller the number here, faster the decoder operation |
`define WB_NUM_OF_DEC_ADDR_LINES 3 |
|
// no. of WISHBONE Slave IMAGES |
// WB image 0 is always used for access to configuration space. In case configuration space access is not implemented, |
// ( both GUEST and NO_CNF_IMAGE defined ), then WB image 0 is not implemented. User doesn't need to define image 0. |
// WB Image 1 is always implemented and user doesnt need to specify its definition |
// WB images' 2 through 5 implementation by defining each one. |
//`define WB_IMAGE2 |
//`define WB_IMAGE3 |
//`define WB_IMAGE4 |
//`define WB_IMAGE5 |
|
// If this define is commented out, then address translation will not be implemented. |
// addresses will pass through bridge unchanged, regardles of address translation enable bits. |
// Address translation also slows down the decoding |
//`define ADDR_TRAN_IMPL |
|
// decode speed for WISHBONE definition - initial cycle on WISHBONE bus will take 1 WS for FAST, 2 WSs for MEDIUM and 3 WSs for slow. |
// slower decode speed can be used, to provide enough time for address to be decoded. |
`define WB_DECODE_FAST |
//`define WB_DECODE_MEDIUM |
//`define WB_DECODE_SLOW |
|
// Base address for Configuration space access from WB bus. This value cannot be changed during runtime |
`define WB_CONFIGURATION_BASE 20'hF300_0 |
|
// Turn registered WISHBONE slave outputs on or off |
// all outputs from WB Slave state machine are registered, if this is defined - WB bus outputs as well as |
// outputs to internals of the core. |
//`define REGISTER_WBS_OUTPUTS |
|
/*----------------------------------------------------------------------------------------------------------- |
Core speed definition - used for simulation and 66MHz Capable bit value in status register indicating 66MHz |
capable device |
-----------------------------------------------------------------------------------------------------------*/ |
`define PCI33 |
//`define PCI66 |
|
/*----------------------------------------------------------------------------------------------------------- |
[000h-00Ch] First 4 DWORDs (32-bit) of PCI configuration header - the same regardless of the HEADER type ! |
Vendor_ID is an ID for a specific vendor defined by PCI_SIG - 2321h does not belong to anyone (e.g. |
Xilinx's Vendor_ID is 10EEh and Altera's Vendor_ID is 1172h). Device_ID and Revision_ID should be used |
together by application. |
-----------------------------------------------------------------------------------------------------------*/ |
`define HEADER_VENDOR_ID 16'h1895 |
`define HEADER_DEVICE_ID 16'h0001 |
`define HEADER_REVISION_ID 8'h01 |
|
// Turn registered WISHBONE master outputs on or off |
// all outputs from WB Master state machine are registered, if this is defined - WB bus outputs as well as |
// outputs to internals of the core. |
`define REGISTER_WBM_OUTPUTS |
|
// MAX Retry counter value for WISHBONE Master state-machine |
// This value is 8-bit because of 8-bit retry counter !!! |
`define WB_RTY_CNT_MAX 8'hff |
|
// define the macro below to disable internal retry generation in the wishbone master interface |
// used when wb master accesses extremly slow devices. |
`define PCI_WBM_NO_RESPONSE_CNT_DISABLE |
|
//`define PCI_WB_REV_B3 |
//`define PCI_WBS_B3_RTY_DISABLE |
|
//`define PCI_WBS_ALLOW_NON_ALLIGNED_CONFIG_ACCESS |
/verilog/pci_master32_sm_if.v
0,0 → 1,790
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pci_master32_sm_if.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:29 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "pci_constants.v" |
`include "bus_commands.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
/*==================================================================== |
Module provides interface between PCI bridge internals and PCI master |
state machine |
====================================================================*/ |
module pci_master32_sm_if |
( |
clk_in, |
reset_in, |
|
// interconnect to pci master state machine |
address_out, |
bc_out, |
data_out, |
data_in, |
be_out, |
req_out, |
rdy_out, |
last_out, |
|
next_data_out, |
next_be_out, |
next_last_out, |
|
// status inputs from master SM |
wait_in, |
wtransfer_in, |
rtransfer_in, |
retry_in, |
rerror_in, |
first_in , |
mabort_in, |
|
|
// WISHBONE WRITE fifo inputs and outputs |
wbw_renable_out, |
wbw_fifo_addr_data_in, |
wbw_fifo_cbe_in, |
wbw_fifo_control_in, |
wbw_fifo_empty_in, |
wbw_fifo_transaction_ready_in, |
|
// WISHBONE READ fifo inputs and outputs |
wbr_fifo_wenable_out, |
wbr_fifo_data_out, |
wbr_fifo_be_out, |
wbr_fifo_control_out, |
|
// delayed transaction control logic inputs and outputs |
del_wdata_in, |
del_complete_out, |
del_req_in, |
del_addr_in, |
del_bc_in, |
del_be_in, |
del_burst_in, |
del_error_out, |
del_rty_exp_out, |
del_we_in, |
|
// configuration space interconnect |
// error reporting |
err_addr_out, |
err_bc_out, |
err_signal_out, |
err_source_out, |
err_rty_exp_out, |
|
cache_line_size_in, |
|
// two signals for pci control and status |
mabort_received_out, |
tabort_received_out, |
|
posted_write_not_present_out |
); |
|
// system inputs |
input clk_in ; |
input reset_in ; |
|
// PCI master state machine interconnect |
output [31:0] address_out ; // address output |
|
output [3:0] bc_out ; // bus command output |
reg [3:0] bc_out ; |
|
output [31:0] data_out ; // data output for writes |
reg [31:0] data_out ; |
|
input [31:0] data_in ; // data input for reads |
output [3:0] be_out ; // byte enable output |
reg [3:0] be_out ; |
|
output req_out ; // request output |
|
output rdy_out ; // ready output |
reg rdy_out ; |
|
output last_out ; // last data indicator output |
|
output [31:0] next_data_out ; // next data output |
output [3:0] next_be_out ; // next byte enable output |
output next_last_out ; // next transfer last indicator |
|
input wait_in, |
wtransfer_in, |
rtransfer_in, |
retry_in, |
rerror_in, |
first_in , |
mabort_in ; |
|
// WISHBONE write fifo interconnect |
output wbw_renable_out ; // WBW_FIFO read enable signal |
|
input [31:0] wbw_fifo_addr_data_in ; // WBW_FIFO address/data bus |
input [3:0] wbw_fifo_cbe_in ; // WBW_FIFO command/byte enable bus |
input [3:0] wbw_fifo_control_in ; // WBW_FIFO control bus |
input wbw_fifo_empty_in ; // WBW_FIFO's empty status indicator |
input wbw_fifo_transaction_ready_in ; // WBW_FIFO transaction ready indicator |
|
// WISHBONE read FIFO interconnect |
output wbr_fifo_wenable_out ; // write enable for WBR_FIFO |
|
output [31:0] wbr_fifo_data_out ; // data output to WBR_FIFO |
|
output [3:0] wbr_fifo_be_out ; // byte enable output for WBR_FIFO |
|
output [3:0] wbr_fifo_control_out ; // WBR_FIFO control output |
|
// delayed transaction control logic inputs and outputs |
input [31:0] del_wdata_in ; // delayed write data input |
output del_complete_out ; // delayed transaction completed output |
|
input del_req_in ; // delayed transaction request |
input [31:0] del_addr_in ; // delayed transaction address |
input [3:0] del_bc_in ; // delayed transaction bus command input |
input [3:0] del_be_in ; // delayed transaction byte enables input |
input del_burst_in ; // delayed transaction burst req. indicator |
output del_error_out ; // delayed transation error termination signal |
|
output del_rty_exp_out ; // retry expired output for delayed transactions |
|
input del_we_in ; // delayed write request indicator |
|
output [31:0] err_addr_out ; // erroneous address output |
output [3:0] err_bc_out ; // erroneous bus command output |
|
output err_signal_out ; // error signalization |
|
output err_source_out ; // error source indicator |
|
input [7:0] cache_line_size_in ; // cache line size value input |
|
output err_rty_exp_out ; // retry expired error output |
|
output mabort_received_out ; // master abort signaled to status register |
output tabort_received_out ; // target abort signaled to status register |
|
output posted_write_not_present_out ; // used in target state machine - must deny read completions when this signal is 0 |
|
|
assign err_bc_out = bc_out ; |
|
// assign read outputs |
/*================================================================================================================== |
WISHBONE read FIFO data outputs - just link them to SM data outputs and delayed BE input |
==================================================================================================================*/ |
assign wbr_fifo_data_out = data_in ; |
assign wbr_fifo_be_out = del_be_in ; |
|
// decode if current bus command is configuration command |
wire conf_cyc_bc = ( bc_out[3:1] == `BC_CONF_RW ) ; |
|
// register for indicating that current data is also last in transfer |
reg current_last ; |
|
// register indicating that last data was transfered OK |
reg last_transfered ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
last_transfered <= #`FF_DELAY 1'b0 ; |
else |
last_transfered <= #`FF_DELAY ~wait_in && last_out && wtransfer_in ; |
end |
|
// status signals output assignement |
assign mabort_received_out = mabort_in ; |
|
wire tabort_ff_in = ~wait_in && rerror_in ; |
|
reg tabort_received_out ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
tabort_received_out <= #`FF_DELAY 1'b0 ; |
else |
tabort_received_out <= #`FF_DELAY tabort_ff_in ; |
end |
|
// error recovery indicator |
reg err_recovery ; |
|
// operation is locked until error recovery is in progress or error bit is not cleared in configuration space |
wire err_lock = err_recovery ; |
|
// three requests are possible - posted write, delayed write and delayed read |
reg del_write_req ; |
reg posted_write_req ; |
reg del_read_req ; |
|
// assign request output |
assign req_out = del_write_req || posted_write_req || del_read_req ; |
|
// posted write is not present, when WB Write Fifo is empty and posted write transaction is not beeing requested at present time |
assign posted_write_not_present_out = !posted_write_req && wbw_fifo_empty_in ; |
|
// write requests are staged, so data is read from source into current data register and next data register |
reg write_req_int ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
write_req_int <= #`FF_DELAY 1'b0 ; |
else |
write_req_int <= #`FF_DELAY posted_write_req || del_write_req ; |
|
end |
|
// ready output is generated one clock after request for reads and two after for writes |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
rdy_out <= #`FF_DELAY 1'b0 ; |
else |
rdy_out <= #`FF_DELAY del_read_req || ( (posted_write_req || del_write_req) && write_req_int) ; |
end |
|
// wires with logic used as inputs to request FFs |
wire do_posted_write = ( wbw_fifo_transaction_ready_in && ~wbw_fifo_empty_in && ~err_lock ) ; |
wire do_del = ( del_req_in && ~err_lock && wbw_fifo_empty_in ) ; |
wire do_del_write = do_del && del_we_in ; |
wire do_del_read = do_del && ~del_we_in ; |
|
// register for indicating current operation's data source |
parameter DELAYED_WRITE = 1'b1 ; |
parameter POSTED_WRITE = 1'b0 ; |
|
// new data source - depending on which transaction will be processed next - delayed read is here because source of byte enables must |
// be specified for delayed reads also - data source is not relevant for delayed reads, so value is don't care anyway |
wire new_data_source = (do_del_write || do_del_read) ? DELAYED_WRITE : POSTED_WRITE ; // input to data source register |
wire data_source_change = ~req_out ; // change (enable) for data source register - when no requests are in progress |
|
reg data_source ; // data source value |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
// default value is posted write source - wbw_fifo |
data_source <= #`FF_DELAY POSTED_WRITE ; |
else |
if (data_source_change) |
// change data source on rising clock edge |
data_source <= #`FF_DELAY new_data_source ; |
end |
|
// multiplexer for data output to PCI MASTER state machine |
reg [31:0] source_data ; |
reg [3:0] source_be ; |
always@(data_source or wbw_fifo_addr_data_in or wbw_fifo_cbe_in or del_wdata_in or del_be_in or del_burst_in) |
begin |
case (data_source) |
POSTED_WRITE: begin |
source_data = wbw_fifo_addr_data_in ; |
source_be = wbw_fifo_cbe_in ; |
end |
DELAYED_WRITE: begin |
source_data = del_wdata_in ; |
// read all bytes during delayed burst read! |
source_be = ~( del_be_in | {4{del_burst_in}} ) ; |
end |
endcase |
end |
|
wire waddr = wbw_fifo_control_in[`ADDR_CTRL_BIT] ; |
|
// address change indicator - address is allowed to be loaded only when no transaction is in progress! |
wire address_change = ~req_out ; // address change - whenever there is no request in progress |
|
// new address - input to register storing address of current request - if posted write request will be next, |
// load address and bus command from wbw_fifo, else load data from delayed transaction logic |
wire [31:0] new_address = ( ~req_out && do_posted_write ) ? wbw_fifo_addr_data_in[31:0] : del_addr_in[31:0] ; |
wire [3:0] new_bc = ( ~req_out && do_posted_write ) ? wbw_fifo_cbe_in : del_bc_in ; |
|
// address counter enable - only for posted writes when data is actually transfered |
wire addr_count_en = ~wait_in && posted_write_req && rtransfer_in ; |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
bc_out <= #`FF_DELAY `BC_RESERVED0 ; |
else |
if (address_change) |
bc_out <= #`FF_DELAY new_bc ; |
end |
|
reg [29:0] current_dword_address ; |
|
// DWORD address counter with load |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
current_dword_address <= #`FF_DELAY 30'h0000_0000 ; |
else |
if (address_change) |
current_dword_address <= #`FF_DELAY new_address[31:2] ; |
else |
if (addr_count_en) |
current_dword_address <= #`FF_DELAY current_dword_address + 1'b1 ; |
end |
|
reg [1:0] current_byte_address ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
current_byte_address <= #`FF_DELAY 2'b00 ; |
else |
if (address_change) |
current_byte_address <= #`FF_DELAY new_address[1:0] ; |
end |
|
// address output to PCI master state machine assignement |
assign address_out = { current_dword_address, current_byte_address } ; |
|
// the same for erroneous address assignement |
assign err_addr_out = { current_dword_address, current_byte_address } ; |
|
// cacheline size counter - for read transaction length control |
// cache line count is enabled during burst reads when data is actually transfered |
wire read_count_enable = ~wait_in && del_read_req && del_burst_in && wtransfer_in ; |
|
// cache line counter is loaded when del read request is not in progress |
wire read_count_load = ~del_read_req ; |
|
reg [(`WBR_ADDR_LENGTH - 1):0] max_read_count ; |
always@(cache_line_size_in or del_bc_in) |
begin |
if ( (cache_line_size_in >= `WBR_DEPTH) || (~del_bc_in[1] && ~del_bc_in[0]) ) |
max_read_count = `WBR_DEPTH - 1'b1; |
else |
max_read_count = cache_line_size_in ; |
end |
|
reg [(`WBR_ADDR_LENGTH - 1):0] read_count ; |
|
// cache line bound indicator - it signals when data for one complete cacheline was read |
wire read_bound_comb = ~|(read_count[(`WBR_ADDR_LENGTH - 1):2]) ; |
reg read_bound ; |
always@(posedge clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
read_bound <= #`FF_DELAY 1'b0 ; |
else if (read_count_load) |
read_bound <= #`FF_DELAY 1'b0 ; |
else if ( read_count_enable ) |
read_bound <= #`FF_DELAY read_bound_comb ; |
end |
|
wire read_count_change_val = read_count_load | read_count_enable ; |
|
wire [(`WBR_ADDR_LENGTH - 1):0] read_count_next = read_count_load ? max_read_count : (read_count - 1'b1) ; |
|
// down counter with load |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
read_count <= #`FF_DELAY 0 ; |
else |
/* if (read_count_load) |
read_count <= #`FF_DELAY max_read_count ; |
else |
if (read_count_enable) |
read_count <= #`FF_DELAY read_count - 1'b1 ; |
*/ if (read_count_change_val) |
read_count <= #`FF_DELAY read_count_next ; |
end |
|
// flip flop indicating error recovery is in progress |
reg err_recovery_in ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
err_recovery <= #`FF_DELAY 1'b0 ; |
else |
err_recovery <= #`FF_DELAY err_recovery_in ; |
end |
|
/*// retry counter implementation |
reg [7:0] retry_count ; |
|
wire retry_expired = ~|(retry_count[7:1]) ; |
|
// loading of retry counter - whenever no request is present or other termination than retry or wait is signalled |
wire retry_load = ~req_out || (~wait_in && rtransfer_in) ; |
|
// retry DOWN counter with load |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
retry_count <= #`FF_DELAY 8'hFF ; |
else |
if ( retry_load ) |
retry_count <= #`FF_DELAY `PCI_RTY_CNT_MAX ; |
else |
if (retry_in) |
retry_count <= #`FF_DELAY retry_count - 1'b1 ; |
end*/ |
|
/*================================================================================================================== |
Delayed write requests are always single transfers! |
Delayed write request starts, when no request is currently beeing processed and it is signaled from other side |
of the bridge. |
==================================================================================================================*/ |
// delayed write request FF input control |
reg del_write_req_input ; |
|
always@( |
do_del_write or |
del_write_req or |
posted_write_req or |
del_read_req or |
wait_in or |
//retry_in or |
//retry_expired or |
rtransfer_in or |
rerror_in or |
mabort_in |
) |
begin |
if (~del_write_req) |
begin |
// delayed write is not in progress and is requested |
// delayed write can be requested when no other request is in progress |
del_write_req_input = ~posted_write_req && ~del_read_req && do_del_write ; |
end |
else |
begin |
// delayed write request is in progress - assign input |
del_write_req_input = wait_in || |
( /*~( retry_in && retry_expired) &&*/ |
~rtransfer_in && ~rerror_in && ~mabort_in |
); |
end |
end |
|
// delayed write request FLIP-FLOP |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
del_write_req <= #`FF_DELAY 1'b0 ; |
else |
del_write_req <= #`FF_DELAY del_write_req_input ; |
end |
|
/*================================================================================================ |
Posted write request indicator. |
Posted write starts whenever no request is in progress and one whole posted write is |
stored in WBW_FIFO. It ends on error terminations ( master, target abort, retry expired) or |
data transfer terminations if last data is on top of FIFO. |
Continues on wait, retry, and disconnect without data. |
================================================================================================*/ |
// posted write request FF input control |
reg posted_write_req_input ; |
always@( |
do_posted_write or |
del_write_req or |
posted_write_req or |
del_read_req or |
wait_in or |
//retry_in or |
rerror_in or |
mabort_in or |
//retry_expired or |
rtransfer_in or |
last_transfered |
) |
begin |
if (~posted_write_req) |
begin |
// posted write is not in progress |
posted_write_req_input = ~del_write_req && ~del_read_req && do_posted_write ; |
end |
else |
begin |
posted_write_req_input = wait_in || |
(/*~(retry_in && retry_expired && ~rtransfer_in) &&*/ |
~rerror_in && ~mabort_in && |
~(last_transfered) |
) ; |
|
end |
end |
|
// posted write request flip flop |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
posted_write_req <= #`FF_DELAY 1'b0 ; |
else |
posted_write_req <= #`FF_DELAY posted_write_req_input ; |
|
end |
|
/*================================================================================================ |
Delayed read request indicator. |
Delayed read starts whenever no request is in progress and delayed read request is signaled from |
other side of bridge. It ends on error terminations ( master, target abort, retry expired) or |
data transfer terminations if it is not burst transfer or on cache line bounds on burst transfer. |
It also ends on disconnects. |
Continues on wait and retry. |
================================================================================================*/ |
// delayed read FF input control |
reg del_read_req_input ; |
always@( |
do_del_read or |
del_write_req or |
posted_write_req or |
del_read_req or |
last_transfered or |
wait_in or |
retry_in or |
//retry_expired or |
mabort_in or |
rtransfer_in or |
rerror_in or |
first_in or |
del_complete_out |
) |
begin |
if (~del_read_req) |
begin |
del_read_req_input = ~del_write_req && ~posted_write_req && ~del_complete_out && do_del_read ; |
end |
else |
begin |
del_read_req_input = wait_in || |
( ~(retry_in && (~first_in /*|| retry_expired */)) && |
~mabort_in && ~rerror_in && |
~(last_transfered) |
) ; |
end |
end |
|
// delayed read request FF |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
del_read_req <= #`FF_DELAY 1'b0 ; |
else |
del_read_req <= #`FF_DELAY del_read_req_input ; |
end |
|
// wire indicating last entry of transaction on top of fifo |
wire wlast = wbw_fifo_control_in[`LAST_CTRL_BIT] ; |
|
wire last_int = posted_write_req && wlast || del_write_req ; |
|
// intermidiate data, byte enable and last registers |
reg [31:0] intermediate_data ; |
reg [3:0] intermediate_be ; |
reg intermediate_last ; |
|
wire intermediate_enable = ( posted_write_req || del_write_req ) && ( ~write_req_int || (( ~rdy_out || ~wait_in && rtransfer_in ) && ~intermediate_last)) ; |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
begin |
intermediate_data <= #`FF_DELAY 32'h0000_0000 ; |
intermediate_be <= #`FF_DELAY 4'h0 ; |
intermediate_last <= #`FF_DELAY 1'b0 ; |
end |
else |
if ( intermediate_enable ) |
begin |
intermediate_data <= #`FF_DELAY source_data ; |
intermediate_be <= #`FF_DELAY source_be ; |
intermediate_last <= #`FF_DELAY last_int ; |
end |
end |
|
// multiplexer for next data |
reg [31:0] next_data_out ; |
reg [3:0] next_be_out ; |
reg write_next_last ; |
reg [3:0] write_next_be ; |
|
always@(rtransfer_in or intermediate_data or intermediate_be or intermediate_last or wbw_fifo_addr_data_in or wbw_fifo_cbe_in or wlast) |
begin |
if( rtransfer_in ) |
begin |
next_data_out = wbw_fifo_addr_data_in ; |
write_next_last = wlast ; |
write_next_be = wbw_fifo_cbe_in ; |
end |
else |
begin |
next_data_out = intermediate_data ; |
write_next_last = intermediate_last ; |
write_next_be = intermediate_be ; |
end |
end |
|
always@(del_read_req or source_be or write_next_be) |
begin |
if (del_read_req) |
next_be_out = source_be ; |
else |
next_be_out = write_next_be ; |
end |
/*================================================================================================ |
WBW_FIFO read enable - read from WBW_FIFO is performed on posted writes, when data transfer |
termination is received - transfer or disconnect with data. Reads are enabled during error |
recovery also, since erroneous transaction must be pulled out of FIFO! |
================================================================================================*/ |
// wbw_fifo read enable input control |
|
assign wbw_renable_out = ~req_out && (do_posted_write || err_recovery) || |
posted_write_req && ( ~write_req_int || (~rdy_out && ~intermediate_last) || (~wait_in && rtransfer_in && ~intermediate_last)) ; |
|
/*================================================================================================ |
WBR_FIFO write enable control - |
writes to FIFO are possible only when delayed read request is in progress and data transfer |
or error termination is signalled. It is not enabled on retry or disconnect without data. |
================================================================================================*/ |
// wbr_fifo write enable control - enabled when transfer is in progress and data is transfered or error is signalled |
assign wbr_fifo_wenable_out = del_read_req && ~wait_in && ( rtransfer_in || mabort_in || rerror_in ) ; |
|
/*================================================================================================ |
WBR_FIFO control output for identifying data entries. |
This is necesary because of prefetched reads, which partially succeed. On error, error entry |
gets in to signal it on WISHBONE bus if WISHBONE master reads up to this entry. |
================================================================================================*/ |
assign wbr_fifo_control_out[`ADDR_CTRL_BIT] = 1'b0 ; |
assign wbr_fifo_control_out[`LAST_CTRL_BIT] = last_transfered ; |
assign wbr_fifo_control_out[`DATA_ERROR_CTRL_BIT] = rerror_in || (mabort_in && ~conf_cyc_bc) ; |
assign wbr_fifo_control_out[`UNUSED_CTRL_BIT] = 1'b0 ; |
|
// retry expired error for posted writes control |
//assign err_rty_exp_out = posted_write_req && ~wait_in && retry_in && retry_expired && ~rtransfer_in; |
assign err_rty_exp_out = 1'b0 ; |
|
// error source and error signal output control logic - only for posted writes |
assign err_source_out = mabort_in /*|| err_rty_exp_out*/ ; |
|
assign err_signal_out = /*err_rty_exp_out || */ posted_write_req && ~wait_in && (mabort_in || rerror_in) ; |
|
//assign del_rty_exp_out = (~wait_in && (del_read_req || del_write_req)) && (retry_in && retry_expired && ~rtransfer_in) ; |
assign del_rty_exp_out = 1'b0 ; |
|
assign del_error_out = ~wait_in && (del_write_req || del_read_req) && ( (mabort_in && ~conf_cyc_bc) || rerror_in ) ; |
|
wire del_write_complete = del_write_req && ( rtransfer_in || rerror_in || mabort_in ) ; |
wire del_read_complete = del_read_req && ( rerror_in || mabort_in || ( last_transfered ) || ( retry_in && ~first_in ) ) ; |
|
assign del_complete_out = ~wait_in && ( del_write_complete || del_read_complete ) ; |
|
// next last output generation |
assign next_last_out = del_write_req || del_read_req && ( ~del_burst_in || read_bound ) || posted_write_req && ( write_next_last ) ; |
/*================================================================================================================== |
Error recovery FF gets a value of one, when during posted write error occurs. It is cleared when all the data provided |
for erroneous transaction is pulled out of WBW_FIFO |
==================================================================================================================*/ |
|
// error recovery flip flop input - used when posted write is terminated with an error |
always@( |
err_recovery or |
last_out or |
wlast or |
err_signal_out or |
intermediate_last |
) |
begin |
// when error recovery is not set - drive its input so it gets set |
if ( ~err_recovery ) |
err_recovery_in = ~last_out && ~intermediate_last && err_signal_out ; |
else |
// when error recovery is set, wbw_fifo is enabled - clear err_recovery when last data entry of erroneous transaction is pulled out of fifo |
err_recovery_in = ~wlast ; |
end |
|
wire data_out_load = (posted_write_req || del_write_req) && ( !rdy_out || ( !wait_in && rtransfer_in ) ) ; |
|
wire be_out_load = (req_out && !rdy_out) || ( posted_write_req && !wait_in && rtransfer_in ) ; |
|
wire last_load = req_out && ( ~rdy_out || ~wait_in && wtransfer_in ) ; |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
data_out <= #`FF_DELAY 32'h0000_0000 ; |
else |
if ( data_out_load ) |
data_out <= #`FF_DELAY intermediate_data ; |
end |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
be_out <= #`FF_DELAY 4'hF ; |
else |
if ( be_out_load ) |
be_out <= #`FF_DELAY posted_write_req ? intermediate_be : source_be ; |
end |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
current_last <= #`FF_DELAY 1'b0 ; |
else |
if ( last_load ) |
current_last <= #`FF_DELAY next_last_out ; |
end |
|
assign last_out = current_last ; |
endmodule |
/verilog/pci_parity_check.v
0,0 → 1,333
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pci_parity_check.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.5 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.4 2002/08/13 11:03:53 mihad |
// Added a few testcases. Repaired wrong reset value for PCI_AM5 register. Repaired Parity Error Detected bit setting. Changed PCI_AM0 to always enabled(regardles of PCI_AM0 define), if image 0 is used as configuration image |
// |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "pci_constants.v" |
`include "bus_commands.v" |
|
module pci_parity_check |
( |
reset_in, |
clk_in, |
pci_par_in, |
pci_par_out, |
pci_par_en_out, |
pci_perr_in, |
pci_perr_out, |
pci_perr_out_in, |
pci_perr_en_out, |
pci_serr_en_in, |
pci_serr_out, |
pci_serr_out_in, |
pci_serr_en_out, |
pci_frame_reg_in, |
pci_frame_en_in, |
pci_irdy_en_in, |
pci_irdy_reg_in, |
pci_trdy_reg_in, |
pci_trdy_en_in, |
pci_par_en_in, |
pci_ad_out_in, |
pci_ad_reg_in, |
pci_cbe_in_in, |
pci_cbe_reg_in, |
pci_cbe_out_in, |
pci_cbe_en_in, |
pci_ad_en_in, |
par_err_response_in, |
par_err_detect_out, |
perr_mas_detect_out, |
|
serr_enable_in, |
sig_serr_out |
|
); |
|
// system inputs |
input reset_in ; |
input clk_in ; |
|
// pci signals that are monitored or generated by parity error checker |
input pci_par_in ; // pci PAR input |
output pci_par_out ; // pci_PAR output |
output pci_par_en_out ; // pci PAR enable output |
input pci_perr_in ; // PERR# input |
output pci_perr_out ; // PERR# output |
output pci_perr_en_out ; // PERR# buffer enable output |
input pci_serr_en_in ; // SERR enable input |
output pci_serr_out ; // SERR# output |
input pci_serr_out_in ; // SERR# output value input |
input pci_perr_out_in ; // PERR# output value input |
output pci_serr_en_out ; // SERR# buffer enable output |
input pci_frame_reg_in ; // frame from pci bus input |
input pci_frame_en_in ; // frame enable driven by master state machine |
input pci_irdy_en_in ; // irdy enable input from PCI master |
input pci_irdy_reg_in ; // irdy from PCI bus |
input pci_trdy_reg_in ; // target ready from PCI bus |
input pci_trdy_en_in ; // target ready output enable |
input pci_par_en_in ; // par enable input |
input [31:0] pci_ad_out_in ; // data driven by bridge to PCI |
input [31:0] pci_ad_reg_in ; // data driven by other agents on PCI |
input [3:0] pci_cbe_in_in ; // cbe driven by outside agents |
input [3:0] pci_cbe_reg_in ; // registered cbe driven by outside agents |
input [3:0] pci_cbe_out_in ; // cbe driven by pci master state machine |
input pci_ad_en_in ; // ad enable input |
input par_err_response_in ; // parity error response bit from conf.space |
output par_err_detect_out ; // parity error detected signal out |
output perr_mas_detect_out ; // master asserted PERR or sampled PERR asserted |
input serr_enable_in ; // system error enable bit from conf.space |
output sig_serr_out ; // signalled system error output for configuration space |
input pci_cbe_en_in ; |
|
// FFs for frame input - used for determining whether PAR is sampled for address phase or for data phase |
reg frame_dec2 ; |
reg check_perr ; |
|
/*======================================================================================================================= |
CBE lines' parity is needed for overall parity calculation |
=======================================================================================================================*/ |
wire par_cbe_out = pci_cbe_out_in[3] ^ pci_cbe_out_in[2] ^ pci_cbe_out_in[1] ^ pci_cbe_out_in[0] ; |
wire par_cbe_in = pci_cbe_reg_in[3] ^ pci_cbe_reg_in[2] ^ pci_cbe_reg_in[1] ^ pci_cbe_reg_in[0] ; |
|
/*======================================================================================================================= |
Parity generator - parity is generated and assigned to output on every clock edge. PAR output enable is active |
one clock cycle after data output enable. Depending on whether master is performing access or target is responding, |
apropriate cbe data is included in parity generation. Non - registered CBE is used during reads through target SM |
=======================================================================================================================*/ |
|
// generate appropriate par signal |
wire data_par = (pci_ad_out_in[31] ^ pci_ad_out_in[30] ^ pci_ad_out_in[29] ^ pci_ad_out_in[28]) ^ |
(pci_ad_out_in[27] ^ pci_ad_out_in[26] ^ pci_ad_out_in[25] ^ pci_ad_out_in[24]) ^ |
(pci_ad_out_in[23] ^ pci_ad_out_in[22] ^ pci_ad_out_in[21] ^ pci_ad_out_in[20]) ^ |
(pci_ad_out_in[19] ^ pci_ad_out_in[18] ^ pci_ad_out_in[17] ^ pci_ad_out_in[16]) ^ |
(pci_ad_out_in[15] ^ pci_ad_out_in[14] ^ pci_ad_out_in[13] ^ pci_ad_out_in[12]) ^ |
(pci_ad_out_in[11] ^ pci_ad_out_in[10] ^ pci_ad_out_in[9] ^ pci_ad_out_in[8]) ^ |
(pci_ad_out_in[7] ^ pci_ad_out_in[6] ^ pci_ad_out_in[5] ^ pci_ad_out_in[4]) ^ |
(pci_ad_out_in[3] ^ pci_ad_out_in[2] ^ pci_ad_out_in[1] ^ pci_ad_out_in[0]) ; |
|
wire par_out_only = data_par ^ par_cbe_out ; |
|
pci_par_crit par_gen |
( |
.par_out (pci_par_out), |
.par_out_in (par_out_only), |
.pci_cbe_en_in (pci_cbe_en_in), |
.data_par_in (data_par), |
.pci_cbe_in (pci_cbe_in_in) |
) ; |
|
// PAR enable = ad output enable delayed by one clock |
assign pci_par_en_out = pci_ad_en_in ; |
|
/*======================================================================================================================= |
Parity checker - parity is checked on every clock cycle. When parity error is detected, appropriate action is taken |
to signal address parity errors on SERR if enabled and data parity errors on PERR# if enabled. Logic also drives |
outputs to configuration space to set appropriate status bits if parity error is detected. PAR signal is checked on |
master read operations or writes through pci target. Master read is performed when master drives irdy output and |
doesn't drive ad lines. Writes through target are performed when target is driving trdy and doesn't drive ad lines. |
=======================================================================================================================*/ |
|
// equation indicating whether to check and generate or not PERR# signal on next cycle |
wire perr_generate = ~pci_par_en_in && ~pci_ad_en_in // par was not generated on this cycle, so it should be checked |
&& ((pci_irdy_en_in && ~pci_trdy_reg_in) || // and master is driving irdy and target is signaling ready |
(pci_trdy_en_in && ~pci_irdy_reg_in)) ; // or target is driving trdy and master is signaling ready |
|
wire data_in_par = (pci_ad_reg_in[31] ^ pci_ad_reg_in[30] ^ pci_ad_reg_in[29] ^ pci_ad_reg_in[28]) ^ |
(pci_ad_reg_in[27] ^ pci_ad_reg_in[26] ^ pci_ad_reg_in[25] ^ pci_ad_reg_in[24]) ^ |
(pci_ad_reg_in[23] ^ pci_ad_reg_in[22] ^ pci_ad_reg_in[21] ^ pci_ad_reg_in[20]) ^ |
(pci_ad_reg_in[19] ^ pci_ad_reg_in[18] ^ pci_ad_reg_in[17] ^ pci_ad_reg_in[16]) ^ |
(pci_ad_reg_in[15] ^ pci_ad_reg_in[14] ^ pci_ad_reg_in[13] ^ pci_ad_reg_in[12]) ^ |
(pci_ad_reg_in[11] ^ pci_ad_reg_in[10] ^ pci_ad_reg_in[9] ^ pci_ad_reg_in[8]) ^ |
(pci_ad_reg_in[7] ^ pci_ad_reg_in[6] ^ pci_ad_reg_in[5] ^ pci_ad_reg_in[4]) ^ |
(pci_ad_reg_in[3] ^ pci_ad_reg_in[2] ^ pci_ad_reg_in[1] ^ pci_ad_reg_in[0]) ; |
|
//wire perr = (cbe_par_reg ^ pci_par_in ^ data_in_par) ; |
wire perr ; |
wire perr_n ; |
wire perr_en ; |
|
assign pci_perr_out = perr_n ; |
|
// parity error output assignment |
//assign pci_perr_out = ~(perr && perr_generate) ; |
|
wire non_critical_par = par_cbe_in ^ data_in_par ; |
|
pci_perr_crit perr_crit_gen |
( |
.perr_out (perr), |
.perr_n_out (perr_n), |
.non_critical_par_in(non_critical_par), |
.pci_par_in (pci_par_in), |
.perr_generate_in (perr_generate) |
) ; |
|
// PERR# enable |
wire pci_perr_en_reg ; |
pci_perr_en_crit perr_en_crit_gen |
( |
.reset_in (reset_in), |
.clk_in (clk_in), |
.perr_en_out (pci_perr_en_out), |
.perr_en_reg_out (pci_perr_en_reg), |
.non_critical_par_in (non_critical_par), |
.pci_par_in (pci_par_in), |
.perr_generate_in (perr_generate), |
.par_err_response_in (par_err_response_in) |
) ; |
|
// address phase decoding |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
frame_dec2 <= #`FF_DELAY 1'b0 ; |
else |
frame_dec2 <= #`FF_DELAY pci_frame_reg_in ; |
end |
|
// address phase parity error checking - done after address phase is detected - which is - when bridge's master is not driving frame, |
// frame was asserted on previous cycle and was not asserted two cycles before. |
wire check_for_serr_on_first = ~pci_frame_reg_in && frame_dec2 && ~pci_frame_en_in ; |
|
reg check_for_serr_on_second ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
check_for_serr_on_second <= #`FF_DELAY 1'b0 ; |
else |
check_for_serr_on_second <= #`FF_DELAY check_for_serr_on_first && ( pci_cbe_reg_in == `BC_DUAL_ADDR_CYC ) ; |
end |
|
wire check_for_serr = check_for_serr_on_first || check_for_serr_on_second ; |
|
wire serr_generate = check_for_serr && serr_enable_in && par_err_response_in ; |
|
pci_serr_en_crit serr_en_crit_gen |
( |
.serr_en_out (pci_serr_en_out), |
.pci_par_in (pci_par_in), |
.non_critical_par_in(non_critical_par), |
.serr_generate_in (serr_generate) |
); |
|
|
// serr is enabled only for reporting errors - route this signal to configuration space |
assign sig_serr_out = pci_serr_en_in ; |
|
// SERR# output is always 0, just enable is driven apropriately |
pci_serr_crit serr_crit_gen |
( |
.serr_out (pci_serr_out), |
.non_critical_par_in (non_critical_par), |
.pci_par_in (pci_par_in), |
.serr_check_in (check_for_serr) |
); |
|
/*======================================================================================================================================= |
Synchronizing mechanism detecting what is supposed to be done - PERR# generation or PERR# checking |
=======================================================================================================================================*/ |
// perr should be checked one clock after PAR is generated |
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
check_perr <= #`FF_DELAY 1'b0 ; |
else |
check_perr <= #`FF_DELAY pci_par_en_in ; |
end |
|
wire perr_sampled_in = ~pci_perr_in && check_perr ; |
reg perr_sampled ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
perr_sampled <= #`FF_DELAY 1'b0 ; |
else |
perr_sampled <= #`FF_DELAY perr_sampled_in ; |
end |
|
// assign output for parity error detected bit |
assign par_err_detect_out = ~pci_serr_out_in || ~pci_perr_out_in ;//|| perr_sampled ; MihaD - removed - detected parity error is set only during Master Reads or Target Writes |
|
// FF indicating that that last operation was done as bus master |
reg frame_and_irdy_en_prev ; |
reg frame_and_irdy_en_prev_prev ; |
reg master_perr_report ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
begin |
master_perr_report <= #`FF_DELAY 1'b0 ; |
frame_and_irdy_en_prev <= #`FF_DELAY 1'b0 ; |
frame_and_irdy_en_prev_prev <= #`FF_DELAY 1'b0 ; |
end |
else |
begin |
master_perr_report <= #`FF_DELAY frame_and_irdy_en_prev_prev ; |
frame_and_irdy_en_prev <= #`FF_DELAY pci_irdy_en_in && pci_frame_en_in ; |
frame_and_irdy_en_prev_prev <= #`FF_DELAY frame_and_irdy_en_prev ; |
end |
end |
|
assign perr_mas_detect_out = master_perr_report && ( (par_err_response_in && perr_sampled) || pci_perr_en_reg ) ; |
|
endmodule |
/verilog/pci_serr_en_crit.v
0,0 → 1,84
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "serr_en_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// This one is used in parity generator/checker for system error (SERR#) output enable generation |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_serr_en_crit |
( |
serr_en_out, |
non_critical_par_in, |
pci_par_in, |
serr_generate_in |
); |
|
output serr_en_out ; |
|
input non_critical_par_in, |
pci_par_in, |
serr_generate_in ; |
|
assign serr_en_out = serr_generate_in && ( non_critical_par_in ^ pci_par_in ) ; |
|
endmodule |
/verilog/pci_perr_crit.v
0,0 → 1,87
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "perr_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// This one is used in parity generator/checker for parity error output (PERR#) |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_perr_crit |
( |
perr_out, |
perr_n_out, |
non_critical_par_in, |
pci_par_in, |
perr_generate_in |
) ; |
|
output perr_out, |
perr_n_out; |
|
input non_critical_par_in, |
pci_par_in, |
perr_generate_in ; |
|
assign perr_out = (non_critical_par_in ^ pci_par_in) && perr_generate_in ; |
assign perr_n_out = ~perr_out ; |
|
endmodule |
/verilog/pci_serr_crit.v
0,0 → 1,84
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "serr_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// This one is used in parity generator/checker for system error (SERR#) output |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_serr_crit |
( |
serr_out, |
non_critical_par_in, |
pci_par_in, |
serr_check_in |
); |
|
output serr_out ; |
|
input non_critical_par_in, |
pci_par_in, |
serr_check_in ; |
|
assign serr_out = ~(serr_check_in && ( non_critical_par_in ^ pci_par_in )) ; |
|
endmodule |
/verilog/pci_par_crit.v
0,0 → 1,87
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "par_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// this one is used in parity generator/checker for calculating parity signal |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_par_crit |
( |
par_out, |
par_out_in, |
pci_cbe_en_in, |
data_par_in, |
pci_cbe_in |
) ; |
|
output par_out ; |
|
input par_out_in, |
pci_cbe_en_in, |
data_par_in ; |
|
input [3:0] pci_cbe_in ; |
|
assign par_out = pci_cbe_en_in ? par_out_in : ( pci_cbe_in[3] ^ pci_cbe_in[2] ^ pci_cbe_in[1] ^ pci_cbe_in[0] ^ data_par_in) ; |
|
endmodule |
/verilog/pci_perr_en_crit.v
0,0 → 1,103
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "perr_en_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2003/01/27 16:49:31 mihad |
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// This one is used in parity generator/checker for parity error (PERR#) output enable driving |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_perr_en_crit |
( |
reset_in, |
clk_in, |
perr_en_out, |
perr_en_reg_out, |
non_critical_par_in, |
pci_par_in, |
perr_generate_in, |
par_err_response_in |
) ; |
output perr_en_out, |
perr_en_reg_out ; |
|
input reset_in, |
clk_in, |
non_critical_par_in, |
pci_par_in, |
perr_generate_in, |
par_err_response_in ; |
|
wire perr = par_err_response_in && perr_generate_in && ( non_critical_par_in ^ pci_par_in ) ; |
|
// PERR# is enabled for two clocks after parity error is detected - one cycle active, another inactive |
reg perr_en_reg_out ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
perr_en_reg_out <= #1 1'b0 ; |
else |
perr_en_reg_out <= #1 perr ; |
end |
|
assign perr_en_out = perr || perr_en_reg_out ; |
|
endmodule |
/verilog/pci_rst_int.v
0,0 → 1,163
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_rst_int.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2002/02/01 14:43:31 mihad |
// *** empty log message *** |
// |
// |
// |
|
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// Module is used to switch appropriate reset and interrupt signals with few logic |
module pci_rst_int |
( |
clk_in, |
// reset signals |
rst_i, |
pci_rstn_in, |
conf_soft_res_in, |
reset, |
pci_rstn_out, |
pci_rstn_en_out, |
rst_o, |
// interrupt signals |
pci_intan_in, |
conf_int_in, |
int_i, |
out_bckp_perr_en_in, |
out_bckp_serr_en_in, |
pci_intan_out, |
pci_intan_en_out, |
int_o, |
conf_isr_int_prop_out |
); |
|
input clk_in; |
// RESET inputs and outputs |
input rst_i; |
input pci_rstn_in; |
input conf_soft_res_in; |
output reset; |
output pci_rstn_out; |
output pci_rstn_en_out; |
output rst_o; |
|
// INTERRUPT inputs and outputs |
input pci_intan_in; |
input conf_int_in; |
input int_i; |
input out_bckp_perr_en_in; |
input out_bckp_serr_en_in; |
output pci_intan_out; |
output pci_intan_en_out; |
output int_o; |
output conf_isr_int_prop_out; |
|
/*-------------------------------------------------------------------------------------------------------- |
RESET logic |
--------------------------------------------------------------------------------------------------------*/ |
assign pci_rstn_out = 1'b0 ; |
// host implementation of the bridge gets its reset from WISHBONE bus - RST_I and propagates it to PCI bus |
`ifdef HOST |
assign reset = rst_i ; |
`ifdef ACTIVE_LOW_OE |
assign pci_rstn_en_out = ~(rst_i || conf_soft_res_in) ; |
`else |
assign pci_rstn_en_out = rst_i || conf_soft_res_in ; |
`endif |
assign rst_o = 1'b0 ; |
`else |
// guest implementation of the bridge gets its reset from PCI bus - RST# and propagates it to WISHBONE bus |
`ifdef GUEST |
assign reset = ~pci_rstn_in ; |
assign rst_o = (~pci_rstn_in) || conf_soft_res_in ; |
`ifdef ACTIVE_LOW_OE |
assign pci_rstn_en_out = 1'b1 ; // disabled |
`else |
assign pci_rstn_en_out = 1'b0 ; // disabled |
`endif |
`endif |
`endif |
|
/*-------------------------------------------------------------------------------------------------------- |
INTERRUPT logic |
--------------------------------------------------------------------------------------------------------*/ |
assign pci_intan_out = 1'b0 ; |
// host implementation of the bridge gets its interrupt from PCI bus - INTA# and propagates it to WISHBONE bus |
`ifdef HOST |
assign conf_isr_int_prop_out = ~pci_intan_in ; |
assign int_o = conf_int_in ; |
`ifdef ACTIVE_LOW_OE |
assign pci_intan_en_out = 1'b1 ; // disabled |
`else |
assign pci_intan_en_out = 1'b0 ; // disabled |
`endif |
`else |
// guest implementation of the bridge gets its interrupt from WISHBONE bus - INT_I and propagates it to PCI bus |
`ifdef GUEST |
wire interrupt_a_en; |
pci_out_reg inta |
( |
.reset_in ( reset ), |
.clk_in ( clk_in) , |
.dat_en_in ( 1'b1 ), |
.en_en_in ( 1'b1 ), |
.dat_in ( 1'b0 ) , // active low |
.en_in ( conf_int_in ) , |
.en_out ( interrupt_a_en ), |
.dat_out ( ) |
); |
assign conf_isr_int_prop_out = int_i ; |
assign int_o = 1'b0 ; |
assign pci_intan_en_out = interrupt_a_en ; |
`endif |
`endif |
|
|
endmodule |
/verilog/pci_mas_ad_en_crit.v
0,0 → 1,79
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "mas_ad_en_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// This module is used in master state machine for AD lines output enable driving |
module pci_mas_ad_en_crit |
( |
pci_ad_en_out, |
ad_en_slow_in, |
ad_en_on_grant_in, |
pci_gnt_in |
) ; |
|
output pci_ad_en_out ; |
input ad_en_slow_in, |
ad_en_on_grant_in, |
pci_gnt_in ; |
|
assign pci_ad_en_out = ad_en_slow_in || (ad_en_on_grant_in && !pci_gnt_in) ; |
|
endmodule |
/verilog/pci_target32_devs_crit.v
0,0 → 1,86
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_target32_devs_crit.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_target32_devs_crit |
( |
devs_w, |
devs_w_frm, |
devs_w_frm_irdy, |
pci_frame_in, |
pci_irdy_in, |
pci_devsel_out |
); |
|
input devs_w ; // devsel signal (composed without critical signals) that do not need critical inputs |
input devs_w_frm ; // devsel signal (composed without critical signals) that needs AND with critical FRAME input |
input devs_w_frm_irdy ; // devsel signal (composed without critical signals) that needs AND with critical FRAME and |
// IRDY inputs |
input pci_frame_in ; // critical constrained input signal |
input pci_irdy_in ; // critical constrained input signal |
|
output pci_devsel_out ; // PCI devsel output |
|
// PCI devsel output with preserved hierarchy for minimum delay! |
assign pci_devsel_out = ~(devs_w || (devs_w_frm && ~pci_frame_in) || (devs_w_frm_irdy && ~pci_frame_in && pci_irdy_in)) ; |
|
|
endmodule |
/verilog/pci_out_reg.v
0,0 → 1,121
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "out_reg.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// module inferes a single IOB output block as known in FPGA architectures |
// It provides data flip flop with clock enable and output enable flip flop with clock enable |
// This is tested in Xilinx FPGA - active low output enable |
// Check polarity of output enable flip flop for specific architecure. |
module pci_out_reg |
( |
reset_in, |
clk_in, |
dat_en_in, |
en_en_in, |
dat_in, |
en_in, |
en_out, |
dat_out |
); |
|
input reset_in, |
clk_in, |
dat_en_in, |
en_en_in, |
dat_in, |
en_in ; |
|
output dat_out ; |
output en_out ; |
|
reg dat_out, |
en_out ; |
|
`ifdef ACTIVE_LOW_OE |
wire en = ~en_in ; |
`else |
`ifdef ACTIVE_HIGH_OE |
wire en = en_in ; |
`endif |
`endif |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
dat_out <= #`FF_DELAY 1'b0 ; |
else if ( dat_en_in ) |
dat_out <= #`FF_DELAY dat_in ; |
end |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
`ifdef ACTIVE_LOW_OE |
en_out <= #`FF_DELAY 1'b1 ; |
`else |
`ifdef ACTIVE_HIGH_OE |
en_out <= #`FF_DELAY 1'b0 ; |
`endif |
`endif |
else if ( en_en_in ) |
en_out <= #`FF_DELAY en ; |
end |
|
endmodule |
/verilog/pci_target32_clk_en.v
0,0 → 1,101
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_target32_clk_en.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_target32_clk_en |
( |
addr_phase, |
config_access, |
addr_claim_in, |
pci_frame_in, |
state_wait, |
state_transfere, |
state_default, |
clk_enable |
); |
|
input addr_phase ; // indicates registered address phase on PCI bus |
input config_access ; // indicates configuration access |
input addr_claim_in ; // indicates claimed input PCI address |
input pci_frame_in ; // critical constrained input signal |
input state_wait ; // indicates WAIT state of FSM |
input state_transfere ; // indicates TRANSFERE state of FSM |
input state_default ; // indicates DEFAULT state of FSM |
|
output clk_enable ; // FSM clock enable output |
|
|
// clock enable signal when FSM is in IDLE state |
wire s_idle_clk_en = ((addr_phase && config_access) || |
(addr_phase && ~config_access && addr_claim_in)) ; |
|
// clock enable signal when FSM is in WAIT state or in DEFAULT state |
wire s_wait_clk_en = (state_wait || state_default) ; |
|
// clock enable signal when FSM is in TRANSFERE state |
wire s_tran_clk_en = (state_transfere && pci_frame_in) ; |
|
|
// Clock enable signal for FSM with preserved hierarchy for minimum delay! |
assign clk_enable = (s_idle_clk_en || s_wait_clk_en || s_tran_clk_en) ; |
|
|
endmodule |
/verilog/pci_target32_stop_crit.v
0,0 → 1,86
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_target32_stop_crit.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_target32_stop_crit |
( |
stop_w, |
stop_w_frm, |
stop_w_frm_irdy, |
pci_frame_in, |
pci_irdy_in, |
pci_stop_out |
); |
|
input stop_w ; // stop signal (composed without critical signals) that do not need critical inputs |
input stop_w_frm ; // stop signal (composed without critical signals) that needs AND with critical FRAME input |
input stop_w_frm_irdy ; // stop signal (composed without critical signals) that needs AND with critical FRAME and |
// IRDY inputs |
input pci_frame_in ; // critical constrained input signal |
input pci_irdy_in ; // critical constrained input signal |
|
output pci_stop_out ; // PCI stop output |
|
// PCI stop output with preserved hierarchy for minimum delay! |
assign pci_stop_out = ~(stop_w || (stop_w_frm && ~pci_frame_in) || (stop_w_frm_irdy && ~pci_frame_in && ~pci_irdy_in)) ; |
|
|
endmodule |
/verilog/pci_wb_addr_mux.v
0,0 → 1,276
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "wb_addr_mux.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2002/08/19 16:54:25 mihad |
// Got rid of undef directives |
// |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// module provides instantiation of address decoders and address multiplexer for various number of implemented wishbone images |
`include "pci_constants.v" |
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_wb_addr_mux |
( |
`ifdef REGISTER_WBS_OUTPUTS |
clk_in, |
reset_in, |
sample_address_in, |
`endif |
address_in, |
bar0_in, |
bar1_in, |
bar2_in, |
bar3_in, |
bar4_in, |
bar5_in, |
am0_in, |
am1_in, |
am2_in, |
am3_in, |
am4_in, |
am5_in, |
ta0_in, |
ta1_in, |
ta2_in, |
ta3_in, |
ta4_in, |
ta5_in, |
at_en_in, |
hit_out, |
address_out |
); |
|
input [31:0] address_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar0_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar1_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar2_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar3_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar4_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar5_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am0_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am1_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am2_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am3_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am4_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am5_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta0_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta1_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta2_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta3_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta4_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta5_in ; |
input [5:0] at_en_in ; |
output [5:0] hit_out ; |
output [31:0] address_out ; |
reg [31:0] address_out ; |
|
wire [31:0] addr0 ; |
wire [31:0] addr1 ; |
wire [31:0] addr2 ; |
wire [31:0] addr3 ; |
wire [31:0] addr4 ; |
wire [31:0] addr5 ; |
|
wire [5:0] hit ; |
assign hit_out = hit ; |
|
`ifdef REGISTER_WBS_OUTPUTS |
input clk_in, reset_in, sample_address_in ; |
|
reg [31:0] address ; |
always@(posedge clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
address <= #`FF_DELAY 0 ; |
else |
if ( sample_address_in ) |
address <= #`FF_DELAY address_in ; |
end |
`else |
wire [31:0] address = address_in ; |
`endif |
|
`ifdef GUEST |
`ifdef NO_CNF_IMAGE |
`else |
`define PCI_WB_ADDR_MUX_DEC0_INCLUDE |
`endif |
`else |
`ifdef HOST |
`define PCI_WB_ADDR_MUX_DEC0_INCLUDE |
`endif |
`endif |
|
`ifdef PCI_WB_ADDR_MUX_DEC0_INCLUDE |
pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec0 |
( |
.hit (hit[0]), |
.addr_out (addr0), |
.addr_in (address), |
.base_addr (bar0_in), |
.mask_addr (am0_in), |
.tran_addr (ta0_in), |
.at_en (1'b0) |
) ; |
`else |
// configuration image not implemented |
assign hit[0] = 1'b0 ; |
assign addr0 = 32'h0000_0000 ; |
`endif |
|
// one image is always implemented |
pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec1 |
( |
.hit (hit[1]), |
.addr_out (addr1), |
.addr_in (address), |
.base_addr (bar1_in), |
.mask_addr (am1_in), |
.tran_addr (ta1_in), |
.at_en (at_en_in[1]) |
) ; |
|
`ifdef WB_IMAGE2 |
pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec2 |
( |
.hit (hit[2]), |
.addr_out (addr2), |
.addr_in (address), |
.base_addr (bar2_in), |
.mask_addr (am2_in), |
.tran_addr (ta2_in), |
.at_en (at_en_in[2]) |
) ; |
|
`else |
assign hit[2] = 1'b0 ; |
assign addr2 = 0 ; |
`endif |
|
`ifdef WB_IMAGE3 |
pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec3 |
( |
.hit (hit[3]), |
.addr_out (addr3), |
.addr_in (address), |
.base_addr (bar3_in), |
.mask_addr (am3_in), |
.tran_addr (ta3_in), |
.at_en (at_en_in[3]) |
) ; |
`else |
assign hit[3] = 1'b0 ; |
assign addr3 = 0 ; |
`endif |
|
`ifdef WB_IMAGE4 |
pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec4 |
( |
.hit (hit[4]), |
.addr_out (addr4), |
.addr_in (address), |
.base_addr (bar4_in), |
.mask_addr (am4_in), |
.tran_addr (ta4_in), |
.at_en (at_en_in[4]) |
) ; |
`else |
assign hit[4] = 1'b0 ; |
assign addr4 = 0 ; |
`endif |
|
`ifdef WB_IMAGE5 |
pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec5 |
( |
.hit (hit[5]), |
.addr_out (addr5), |
.addr_in (address), |
.base_addr (bar5_in), |
.mask_addr (am5_in), |
.tran_addr (ta5_in), |
.at_en (at_en_in[5]) |
) ; |
`else |
assign hit[5] = 1'b0 ; |
assign addr5 = 0 ; |
`endif |
|
// address multiplexer |
always@ |
( |
hit or |
addr0 or |
addr1 or |
addr2 or |
addr3 or |
addr4 or |
addr5 |
) |
begin |
case ( {hit[5:2], hit[0]} ) |
5'b0_0_0_0_1: address_out = addr0 ; |
5'b0_0_0_1_0: address_out = addr2 ; |
5'b0_0_1_0_0: address_out = addr3 ; |
5'b0_1_0_0_0: address_out = addr4 ; |
5'b1_0_0_0_0: address_out = addr5 ; |
|
// default address is address from decoder 1 - it is always implemented - in case of stripped down core to only one image |
// this multiplexer can be completely removed during synthesys |
default: address_out = addr1 ; |
endcase |
end |
|
endmodule |
/verilog/pci_async_reset_flop.v
0,0 → 1,99
//=========================================================================== |
// $Id: pci_async_reset_flop.v,v 1.1 2003-01-27 16:49:31 mihad Exp $ |
// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// async_reset_flop //// |
//// //// |
//// This file is part of the general opencores effort. //// |
//// <http://www.opencores.org/cores/misc/> //// |
//// //// |
//// Module Description: //// |
//// //// |
//// Make a rising-edge triggered flop with async reset with a //// |
//// distinguished name so that it's output can be easily //// |
//// traced, because it is used for asynchronous reset of some //// |
//// flip-flops. //// |
//// //// |
//// This flop should be used instead of a regular flop for ALL //// |
//// asynchronous-reset generator flops. //// |
//// //// |
//// To Do: //// |
//// Nothing //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/08/14 16:44:19 mihad |
// Include statement was enclosed in synosys translate off/on directive - repaired |
// |
// Revision 1.2 2002/02/25 15:15:43 mihad |
// Added include statement that was missing and causing errors |
// |
// Revision 1.1 2002/02/01 14:43:31 mihad |
// *** empty log message *** |
// |
// |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
`include "pci_constants.v" |
|
module pci_async_reset_flop ( |
data_in, clk_in, async_reset_data_out, reset_in |
); |
|
input data_in; |
input clk_in; |
output async_reset_data_out; |
input reset_in; |
|
reg async_reset_data_out; |
|
always @(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
async_reset_data_out <= #`FF_DELAY 1'b0; |
end |
else |
begin |
async_reset_data_out <= #`FF_DELAY data_in; |
end |
end |
|
endmodule |
|
/verilog/pci_master32_sm.v
0,0 → 1,612
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pci_master32_sm.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2003/01/21 16:06:56 mihad |
// Bug fixes, testcases added. |
// |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:29 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// module includes pci master state machine and surrounding logic |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "pci_constants.v" |
|
module pci_master32_sm |
( |
// system inputs |
clk_in, |
reset_in, |
// arbitration |
pci_req_out, |
pci_gnt_in, |
// master in/outs |
pci_frame_in, |
pci_frame_out, |
pci_frame_out_in, |
pci_frame_load_out, |
pci_frame_en_in, |
pci_frame_en_out, |
pci_irdy_in, |
pci_irdy_out, |
pci_irdy_en_out, |
|
// target response inputs |
pci_trdy_in, |
pci_trdy_reg_in, |
pci_stop_in, |
pci_stop_reg_in, |
pci_devsel_in, |
pci_devsel_reg_in, |
|
// address, data, bus command, byte enable in/outs |
pci_ad_reg_in, |
pci_ad_out, |
pci_ad_en_out, |
pci_cbe_out, |
pci_cbe_en_out, |
|
// other side of state machine |
address_in, |
bc_in, |
data_in, |
data_out, |
be_in, |
req_in, |
rdy_in, |
last_in, |
next_data_in, |
next_be_in, |
next_last_in, |
ad_load_out, |
ad_load_on_transfer_out, |
wait_out, |
wtransfer_out, |
rtransfer_out, |
retry_out, |
rerror_out, |
first_out, |
mabort_out, |
latency_tim_val_in |
) ; |
|
// system inputs |
input clk_in, |
reset_in ; |
|
/*================================================================================================================== |
PCI interface signals - bidirectional signals are divided to inputs and outputs in I/O cells instantiation |
module. Enables are separate signals. |
==================================================================================================================*/ |
// arbitration |
output pci_req_out ; |
|
input pci_gnt_in ; |
|
// master in/outs |
input pci_frame_in ; |
input pci_frame_en_in ; |
input pci_frame_out_in ; |
|
output pci_frame_out, |
pci_frame_en_out ; |
|
output pci_frame_load_out ; |
|
input pci_irdy_in ; |
output pci_irdy_out, |
pci_irdy_en_out; |
|
// target response inputs |
input pci_trdy_in, |
pci_trdy_reg_in, |
pci_stop_in, |
pci_stop_reg_in, |
pci_devsel_in, |
pci_devsel_reg_in ; |
|
// address, data, bus command, byte enable in/outs |
input [31:0] pci_ad_reg_in ; |
output [31:0] pci_ad_out ; |
|
reg [31:0] pci_ad_out ; |
|
output pci_ad_en_out ; |
|
output [3:0] pci_cbe_out ; |
|
reg [3:0] pci_cbe_out ; |
|
output pci_cbe_en_out ; |
|
input [31:0] address_in ; // current request address input |
|
input [3:0] bc_in ; // current request bus command input |
|
input [31:0] data_in ; // current dataphase data input |
|
output [31:0] data_out ; // for read operations - current request data output |
|
reg [31:0] data_out ; |
|
input [3:0] be_in ; // current dataphase byte enable inputs |
|
input req_in ; // initiator cycle is requested |
input rdy_in ; // requestor indicates that data is ready to be sent for write transaction and ready to |
// be received on read transaction |
input last_in ; // last dataphase in current transaction indicator |
|
// status outputs |
output wait_out, // wait indicates to the backend that dataphases are not in progress on PCI bus |
wtransfer_out, // on any rising clock edge that this status is 1, data is transferred - heavy constraints here |
rtransfer_out, // registered transfer indicator - when 1 indicates that data was transfered on previous clock cycle |
retry_out, // retry status output - when target signals a retry |
rerror_out, // registered error output - when 1 indicates that error was signalled by a target on previous clock cycle |
first_out , // indicates whether or not any data was transfered in current transaction |
mabort_out; // master abort indicator |
|
reg wait_out ; |
|
// latency timer value input - state machine starts latency timer whenever it starts a transaction and last is not |
// asserted ( meaning burst transfer ). |
input [7:0] latency_tim_val_in ; |
|
// next data, byte enable and last inputs |
input [31:0] next_data_in ; |
input [3:0] next_be_in ; |
input next_last_in ; |
|
// clock enable for data output flip-flops - whenever data is transfered, sm loads next data to those flip flops |
output ad_load_out, |
ad_load_on_transfer_out ; |
|
// parameters - states - one hot |
// idle state |
parameter S_IDLE = 4'h1 ; |
|
// address state |
parameter S_ADDRESS = 4'h2 ; |
|
// transfer state - dataphases |
parameter S_TRANSFER = 4'h4 ; |
|
// turn arround state |
parameter S_TA_END = 4'h8 ; |
|
// change state - clock enable for sm state register |
wire change_state ; |
// next state for state machine |
reg [3:0] next_state ; |
// SM state register |
reg [3:0] cur_state ; |
|
// variables for indicating which state state machine is in |
// this variables are used to reduce logic levels in case of heavily constrained PCI signals |
reg sm_idle ; |
reg sm_address ; |
reg sm_data_phases ; |
reg sm_turn_arround ; |
|
// state machine register control logic with clock enable |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
cur_state <= #`FF_DELAY S_IDLE ; |
else |
if ( change_state ) |
cur_state <= #`FF_DELAY next_state ; |
end |
|
// parameters - data selector - ad and bc lines switch between address/data and bus command/byte enable respectively |
parameter SEL_ADDR_BC = 2'b01 ; |
parameter SEL_DATA_BE = 2'b00 ; |
parameter SEL_NEXT_DATA_BE = 2'b11 ; |
|
reg [1:0] wdata_selector ; |
|
wire u_dont_have_pci_bus = pci_gnt_in || ~pci_frame_in || ~pci_irdy_in ; // pci master can't start a transaction when GNT is deasserted ( 1 ) or |
// bus is not in idle state ( FRAME and IRDY both 1 ) |
wire u_have_pci_bus = ~pci_gnt_in && pci_frame_in && pci_irdy_in ; |
|
// decode count enable - counter that counts cycles passed since address phase |
wire sm_decode_count_enable = sm_data_phases ; // counter is enabled when master wants to transfer |
wire decode_count_enable = sm_decode_count_enable && pci_trdy_in && pci_stop_in && pci_devsel_in ; // and target is not responding |
wire decode_count_load = ~decode_count_enable ; |
reg [2:0] decode_count ; |
|
wire decode_to = ~( decode_count[2] || decode_count[1]) ; |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
// initial value of counter is 4 |
decode_count <= #`FF_DELAY 3'h4 ; |
else |
if ( decode_count_load ) |
decode_count <= #`FF_DELAY 3'h4 ; |
else |
if ( decode_count_enable ) |
decode_count <= #`FF_DELAY decode_count - 1'b1 ; |
end |
|
// Bus commands LSbit indicates whether operation is a read or a write |
wire do_write = bc_in[0] ; |
|
// latency timer |
reg [7:0] latency_timer ; |
|
wire latency_time_out = ~( |
(latency_timer[7] || latency_timer[6] || latency_timer[5] || latency_timer[4]) || |
(latency_timer[3] || latency_timer[2] || latency_timer[1] ) |
) ; |
|
wire latency_timer_enable = (sm_address || sm_data_phases) && ~latency_time_out ; |
wire latency_timer_load = ~sm_address && ~sm_data_phases ; |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
latency_timer <= #`FF_DELAY 8'h00 ; |
else |
if ( latency_timer_load ) |
latency_timer <= #`FF_DELAY latency_tim_val_in ; |
else |
if ( latency_timer_enable) // latency timer counts down until it expires - then it stops |
latency_timer <= #`FF_DELAY latency_timer - 1'b1 ; |
end |
|
// master abort indicators - when decode time out occurres and still no target response is received |
wire do_master_abort = decode_to && pci_trdy_in && pci_stop_in && pci_devsel_in ; |
reg mabort1 ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
mabort1 <= #`FF_DELAY 1'b0 ; |
else |
mabort1 <= #`FF_DELAY do_master_abort ; |
end |
|
reg mabort2 ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
mabort2 <= #`FF_DELAY 1'b0 ; |
else |
mabort2 <= #`FF_DELAY mabort1 ; |
end |
|
// master abort is only asserted for one clock cycle |
assign mabort_out = mabort1 && ~mabort2 ; |
|
// register indicating when master should do timeout termination (latency timer expires) |
reg timeout ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
timeout <= #`FF_DELAY 1'b0 ; |
else |
timeout <= #`FF_DELAY (latency_time_out && ~pci_frame_out_in && pci_gnt_in || timeout ) && ~wait_out ; |
end |
|
wire timeout_termination = sm_turn_arround && timeout && pci_stop_reg_in ; |
|
// frame control logic |
// frame is forced to 0 (active) when state machine is in idle state, since only possible next state is address state which always drives frame active |
wire force_frame = ~sm_idle ; |
// slow signal for frame calculated from various registers in the core |
wire slow_frame = last_in || (latency_time_out && pci_gnt_in) || (next_last_in && sm_data_phases) || mabort1 ; |
// critical timing frame logic in separate module - some combinations of target signals force frame to inactive state immediately after sampled asserted |
// (STOP) |
pci_frame_crit frame_iob_feed |
( |
.pci_frame_out (pci_frame_out), |
.force_frame_in (force_frame), |
.slow_frame_in (slow_frame), |
.pci_stop_in (pci_stop_in) |
) ; |
|
// frame IOB flip flop's clock enable signal |
// slow clock enable - calculated from internal - non critical paths |
wire frame_load_slow = sm_idle || sm_address || mabort1 ; |
|
// critical clock enable for frame IOB in separate module - target response signals actually allow frame value change - critical timing |
pci_frame_load_crit frame_iob_ce |
( |
.pci_frame_load_out (pci_frame_load_out), |
.sm_data_phases_in (sm_data_phases), |
.frame_load_slow_in (frame_load_slow), |
.pci_trdy_in (pci_trdy_in), |
.pci_stop_in (pci_stop_in) |
) ; |
|
// IRDY driving |
// non critical path for IRDY calculation |
wire irdy_slow = pci_frame_out_in && mabort1 || mabort2 ; |
|
// critical path in separate module |
pci_irdy_out_crit irdy_iob_feed |
( |
.pci_irdy_out (pci_irdy_out), |
.irdy_slow_in (irdy_slow), |
.pci_frame_out_in (pci_frame_out_in), |
.pci_trdy_in (pci_trdy_in), |
.pci_stop_in (pci_stop_in) |
) ; |
|
// transfer FF indicator - when first transfer occurs it is set to 1 so backend can distinguish between disconnects and retries. |
wire sm_transfer = sm_data_phases ; |
reg transfer ; |
|
wire transfer_input = sm_transfer && (~(pci_trdy_in || pci_devsel_in) || transfer) ; |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
transfer <= #`FF_DELAY 1'b0 ; |
else |
transfer <= #`FF_DELAY transfer_input ; |
end |
|
assign first_out = ~transfer ; |
|
// fast transfer status output - it's only negated target ready, since wait indicator qualifies valid transfer |
assign wtransfer_out = ~pci_trdy_in ; |
|
// registered transfer status output - calculated from registered target response inputs |
assign rtransfer_out = ~(pci_trdy_reg_in || pci_devsel_reg_in) ; |
|
// registered error status - calculated from registered target response inputs |
assign rerror_out = (~pci_stop_reg_in && pci_devsel_reg_in) ; |
|
// retry is signalled to backend depending on registered target response or when latency timer expires |
assign retry_out = timeout_termination || (~pci_stop_reg_in && ~pci_devsel_reg_in) ; |
|
// AD output flip flops' clock enable |
// new data is loaded to AD outputs whenever state machine is idle, bus was granted and bus is in idle state or |
// when address phase is about to be finished |
wire ad_load_slow = sm_address ; |
wire ad_load_on_grant = sm_idle && pci_frame_in && pci_irdy_in ; |
|
pci_mas_ad_load_crit mas_ad_load_feed |
( |
.ad_load_out (ad_load_out), |
.ad_load_in (ad_load_slow), |
.ad_load_on_grant_in (ad_load_on_grant), |
.pci_gnt_in (pci_gnt_in) |
); |
|
// next data loading is allowed when state machine is in transfer state and operation is a write |
assign ad_load_on_transfer_out = sm_data_phases && do_write ; |
|
// request for a bus is issued anytime when backend is requesting a transaction and state machine is in idle state |
assign pci_req_out = ~(req_in && sm_idle) ; |
|
// change state signal is actually clock enable for state register |
// Non critical path for state change enable: |
// state is always changed when: |
// - address phase is finishing |
// - state machine is in turn arround state |
// - state machine is in transfer state and master abort termination is in progress |
|
wire ch_state_slow = sm_address || sm_turn_arround || sm_data_phases && ( pci_frame_out_in && mabort1 || mabort2 ) ; |
|
// a bit more critical change state enable is calculated with GNT signal |
wire ch_state_med = ch_state_slow || sm_idle && u_have_pci_bus && req_in && rdy_in ; |
|
// most critical change state enable - calculated from target response signals |
pci_mas_ch_state_crit state_machine_ce |
( |
.change_state_out (change_state), |
.ch_state_med_in (ch_state_med), |
.sm_data_phases_in (sm_data_phases), |
.pci_trdy_in (pci_trdy_in), |
.pci_stop_in (pci_stop_in) |
) ; |
|
// ad enable driving |
// also divided in several categories - from less critical to most critical in separate module |
//wire ad_en_slowest = do_write && (sm_address || sm_data_phases && ~pci_frame_out_in) ; |
//wire ad_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ; |
//wire ad_en_slow = ad_en_on_grant && ~pci_gnt_in || ad_en_slowest ; |
//wire ad_en_keep = sm_data_phases && do_write && (pci_frame_out_in && ~mabort1 && ~mabort2) ; |
|
wire ad_en_slow = do_write && ( sm_address || ( sm_data_phases && !( ( pci_frame_out_in && mabort1 ) || mabort2 ) ) ) ; |
wire ad_en_on_grant = ( sm_idle && pci_frame_in && pci_irdy_in ) || sm_turn_arround ; |
|
// critical timing ad enable - calculated from grant input |
pci_mas_ad_en_crit ad_iob_oe_feed |
( |
.pci_ad_en_out (pci_ad_en_out), |
.ad_en_slow_in (ad_en_slow), |
.ad_en_on_grant_in (ad_en_on_grant), |
.pci_gnt_in (pci_gnt_in) |
) ; |
|
// cbe enable driving |
wire cbe_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ; |
wire cbe_en_slow = cbe_en_on_grant && ~pci_gnt_in || sm_address || sm_data_phases && ~pci_frame_out_in ; |
wire cbe_en_keep = sm_data_phases && pci_frame_out_in && ~mabort1 && ~mabort2 ; |
|
// most critical cbe enable in separate module - calculated with most critical target inputs |
pci_cbe_en_crit cbe_iob_feed |
( |
.pci_cbe_en_out (pci_cbe_en_out), |
.cbe_en_slow_in (cbe_en_slow), |
.cbe_en_keep_in (cbe_en_keep), |
.pci_stop_in (pci_stop_in), |
.pci_trdy_in (pci_trdy_in) |
|
) ; |
|
// IRDY enable is equal to FRAME enable delayed for one clock |
assign pci_irdy_en_out = pci_frame_en_in ; |
|
// frame enable driving - sometimes it's calculated from non critical paths |
wire frame_en_slow = (sm_idle && u_have_pci_bus && req_in && rdy_in) || sm_address || (sm_data_phases && ~pci_frame_out_in) ; |
wire frame_en_keep = sm_data_phases && pci_frame_out_in && ~mabort1 && ~mabort2 ; |
|
// most critical frame enable - calculated from heavily constrained target inputs in separate module |
pci_frame_en_crit frame_iob_en_feed |
( |
.pci_frame_en_out (pci_frame_en_out), |
.frame_en_slow_in (frame_en_slow), |
.frame_en_keep_in (frame_en_keep), |
.pci_stop_in (pci_stop_in), |
.pci_trdy_in (pci_trdy_in) |
) ; |
|
// state machine next state definitions |
always@( |
cur_state or |
do_write or |
pci_frame_out_in |
) |
begin |
// default values for state machine outputs |
wait_out = 1'b1 ; |
wdata_selector = SEL_ADDR_BC ; |
sm_idle = 1'b0 ; |
sm_address = 1'b0 ; |
sm_data_phases = 1'b0 ; |
sm_turn_arround = 1'b0 ; |
|
case ( cur_state ) |
|
S_IDLE: begin |
// indicate the state |
sm_idle = 1'b1 ; |
// assign next state - only possible is address - if state machine is supposed to stay in idle state |
// outside signals disable the clock |
next_state = S_ADDRESS ; |
wdata_selector = SEL_DATA_BE ; |
end |
|
S_ADDRESS: begin |
// indicate the state |
sm_address = 1'b1 ; |
// select appropriate data/be for outputs |
wdata_selector = SEL_NEXT_DATA_BE ; |
// only possible next state is transfer state |
next_state = S_TRANSFER ; |
end |
|
S_TRANSFER: begin |
// during transfers wait indicator is inactive - all status signals are now valid |
wait_out = 1'b0 ; |
// indicate the state |
sm_data_phases = 1'b1 ; |
// select appropriate data/be for outputs |
wdata_selector = SEL_NEXT_DATA_BE ; |
if ( pci_frame_out_in ) |
begin |
// when frame is inactive next state will be turn arround |
next_state = S_TA_END ; |
end |
else |
// while frame is active state cannot be anything else then transfer |
next_state = S_TRANSFER ; |
end |
|
S_TA_END: begin |
// wait is still inactive because of registered statuses |
wait_out = 1'b0 ; |
// indicate the state |
sm_turn_arround = 1'b1 ; |
// next state is always idle |
next_state = S_IDLE ; |
end |
default: next_state = S_IDLE ; |
endcase |
end |
|
// ad and cbe lines multiplexer for write data |
reg [1:0] rdata_selector ; |
always@(posedge clk_in or posedge reset_in) |
begin |
if ( reset_in ) |
rdata_selector <= #`FF_DELAY SEL_ADDR_BC ; |
else |
if ( change_state ) |
rdata_selector <= #`FF_DELAY wdata_selector ; |
end |
|
always@(rdata_selector or address_in or bc_in or data_in or be_in or next_data_in or next_be_in) |
begin |
case ( rdata_selector ) |
SEL_ADDR_BC: begin |
pci_ad_out = address_in ; |
pci_cbe_out = bc_in ; |
end |
|
SEL_DATA_BE: begin |
pci_ad_out = data_in ; |
pci_cbe_out = be_in ; |
end |
SEL_NEXT_DATA_BE, |
2'b10: begin |
pci_ad_out = next_data_in ; |
pci_cbe_out = next_be_in ; |
end |
endcase |
end |
|
// data output mux for reads |
always@(mabort_out or pci_ad_reg_in) |
begin |
if ( mabort_out ) |
data_out = 32'hFFFF_FFFF ; |
else |
data_out = pci_ad_reg_in ; |
end |
endmodule |
/verilog/pci_in_reg.v
0,0 → 1,150
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_in_reg.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:29 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "pci_constants.v" |
// Module is used for registering PCI input signals |
// It provides data flip flops with reset |
module pci_in_reg |
( |
reset_in, |
clk_in, |
|
pci_gnt_in, |
pci_frame_in, |
pci_irdy_in, |
pci_trdy_in, |
pci_stop_in, |
pci_devsel_in, |
pci_idsel_in, |
pci_ad_in, |
pci_cbe_in, |
|
pci_gnt_reg_out, |
pci_frame_reg_out, |
pci_irdy_reg_out, |
pci_trdy_reg_out, |
pci_stop_reg_out, |
pci_devsel_reg_out, |
pci_idsel_reg_out, |
pci_ad_reg_out, |
pci_cbe_reg_out |
|
); |
|
input reset_in, clk_in ; |
|
input pci_gnt_in ; |
input pci_frame_in ; |
input pci_irdy_in ; |
input pci_trdy_in ; |
input pci_stop_in ; |
input pci_devsel_in ; |
input pci_idsel_in ; |
input [31:0] pci_ad_in ; |
input [3:0] pci_cbe_in ; |
|
output pci_gnt_reg_out ; |
output pci_frame_reg_out ; |
output pci_irdy_reg_out ; |
output pci_trdy_reg_out ; |
output pci_stop_reg_out ; |
output pci_devsel_reg_out ; |
output pci_idsel_reg_out ; |
output [31:0] pci_ad_reg_out ; |
output [3:0] pci_cbe_reg_out ; |
|
|
reg pci_gnt_reg_out ; |
reg pci_frame_reg_out ; |
reg pci_irdy_reg_out ; |
reg pci_trdy_reg_out ; |
reg pci_stop_reg_out ; |
reg pci_devsel_reg_out ; |
reg pci_idsel_reg_out ; |
reg [31:0] pci_ad_reg_out ; |
reg [3:0] pci_cbe_reg_out ; |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
begin |
pci_gnt_reg_out <= #`FF_DELAY 1'b1 ; |
pci_frame_reg_out <= #`FF_DELAY 1'b1 ; |
pci_irdy_reg_out <= #`FF_DELAY 1'b1 ; |
pci_trdy_reg_out <= #`FF_DELAY 1'b1 ; |
pci_stop_reg_out <= #`FF_DELAY 1'b1 ; |
pci_devsel_reg_out <= #`FF_DELAY 1'b1 ; |
pci_idsel_reg_out <= #`FF_DELAY 1'b0 ; // active high! |
pci_ad_reg_out <= #`FF_DELAY 32'h0000_0000 ; |
pci_cbe_reg_out <= #`FF_DELAY 4'h0 ; |
end |
else |
begin |
pci_gnt_reg_out <= #`FF_DELAY pci_gnt_in ; |
pci_frame_reg_out <= #`FF_DELAY pci_frame_in ; |
pci_irdy_reg_out <= #`FF_DELAY pci_irdy_in ; |
pci_trdy_reg_out <= #`FF_DELAY pci_trdy_in ; |
pci_stop_reg_out <= #`FF_DELAY pci_stop_in ; |
pci_devsel_reg_out <= #`FF_DELAY pci_devsel_in ; |
pci_idsel_reg_out <= #`FF_DELAY pci_idsel_in ; |
pci_ad_reg_out <= #`FF_DELAY pci_ad_in ; |
pci_cbe_reg_out <= #`FF_DELAY pci_cbe_in ; |
end |
end |
|
endmodule |
/verilog/pci_mas_ad_load_crit.v
0,0 → 1,67
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "mas_ad_load_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2002/02/01 14:43:31 mihad |
// *** empty log message *** |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// module is included for loading output flip - flops by monitoring timing critical GNT pci input |
module pci_mas_ad_load_crit |
( |
ad_load_out, |
ad_load_in, |
ad_load_on_grant_in, |
pci_gnt_in |
); |
output ad_load_out ; |
input ad_load_in, |
ad_load_on_grant_in, |
pci_gnt_in ; |
|
assign ad_load_out = ad_load_in || ( ad_load_on_grant_in && !pci_gnt_in ) ; |
endmodule |
/verilog/pci_io_mux_ad_en_crit.v
0,0 → 1,72
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pci_io_mux_ad_en_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2002/02/01 14:43:31 mihad |
// *** empty log message *** |
// |
// |
|
// module provides equation for ad output enables, which uses critical pci bus inputs |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// module is provided for ad bus output enable Flip-Flops values |
module pci_io_mux_ad_en_crit |
( |
ad_en_in, |
pci_frame_in, |
pci_trdy_in, |
pci_stop_in, |
ad_en_out |
); |
input ad_en_in, |
pci_frame_in, |
pci_trdy_in, |
pci_stop_in ; |
output ad_en_out ; |
|
assign ad_en_out = ad_en_in && ( ~pci_frame_in || (pci_trdy_in && pci_stop_in) ) ; |
endmodule |
/verilog/pci_frame_crit.v
0,0 → 1,80
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "frame_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// this one is used in master state machine for driving correct value of frame output |
|
module pci_frame_crit |
( |
pci_frame_out, |
force_frame_in, |
slow_frame_in, |
pci_stop_in |
) ; |
|
output pci_frame_out ; |
input force_frame_in, |
slow_frame_in, |
pci_stop_in ; |
|
assign pci_frame_out = force_frame_in && (slow_frame_in || ~pci_stop_in) ; |
|
endmodule |
/verilog/pci_delayed_write_reg.v
0,0 → 1,92
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "delayed_write_reg.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_delayed_write_reg |
( |
reset_in, |
req_clk_in, |
comp_wdata_out, |
req_we_in, |
req_wdata_in |
); |
|
// system inputs |
input reset_in, |
req_clk_in ; // request clock input |
|
output [31:0] comp_wdata_out ; // data output |
|
input req_we_in ; // write enable input |
input [31:0] req_wdata_in ; // data input - latched with posedge of req_clk_in when req_we_in is high |
|
reg [31:0] comp_wdata_out ; |
|
// write request operation |
always@(posedge req_clk_in or posedge reset_in) |
begin |
if (reset_in) |
comp_wdata_out <= #`FF_DELAY 32'h0000_0000 ; |
else |
if (req_we_in) |
comp_wdata_out <= #`FF_DELAY req_wdata_in ; |
end |
|
endmodule // DELAYED_WRITE_REG |
/verilog/pci_conf_cyc_addr_dec.v
0,0 → 1,116
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "conf_cyc_addr_dec.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
|
// module is a simple decoder which decodes device num field of configuration address |
// for type0 configuration cycles. If type 1 configuration cycle is |
// initiated then address goes through unchanged |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_conf_cyc_addr_dec |
( |
ccyc_addr_in, |
ccyc_addr_out |
) ; |
|
input [31:0] ccyc_addr_in ; |
output [31:0] ccyc_addr_out ; |
reg [31:11] ccyc_addr_31_11 ; |
|
// lower 11 address lines are alweys going through unchanged |
assign ccyc_addr_out = {ccyc_addr_31_11, ccyc_addr_in[10:0]} ; |
|
// configuration cycle type indicator |
wire ccyc_type = ccyc_addr_in[0] ; |
|
always@(ccyc_addr_in or ccyc_type) |
begin |
if (ccyc_type) |
// type 1 cycle - address goes through unchanged |
ccyc_addr_31_11 = ccyc_addr_in[31:11] ; |
else |
begin |
// type 0 conf. cycle - decode device number field to appropriate value |
case (ccyc_addr_in[15:11]) |
5'h00:ccyc_addr_31_11 = 21'h00_0001 ; |
5'h01:ccyc_addr_31_11 = 21'h00_0002 ; |
5'h02:ccyc_addr_31_11 = 21'h00_0004 ; |
5'h03:ccyc_addr_31_11 = 21'h00_0008 ; |
5'h04:ccyc_addr_31_11 = 21'h00_0010 ; |
5'h05:ccyc_addr_31_11 = 21'h00_0020 ; |
5'h06:ccyc_addr_31_11 = 21'h00_0040 ; |
5'h07:ccyc_addr_31_11 = 21'h00_0080 ; |
5'h08:ccyc_addr_31_11 = 21'h00_0100 ; |
5'h09:ccyc_addr_31_11 = 21'h00_0200 ; |
5'h0A:ccyc_addr_31_11 = 21'h00_0400 ; |
5'h0B:ccyc_addr_31_11 = 21'h00_0800 ; |
5'h0C:ccyc_addr_31_11 = 21'h00_1000 ; |
5'h0D:ccyc_addr_31_11 = 21'h00_2000 ; |
5'h0E:ccyc_addr_31_11 = 21'h00_4000 ; |
5'h0F:ccyc_addr_31_11 = 21'h00_8000 ; |
5'h10:ccyc_addr_31_11 = 21'h01_0000 ; |
5'h11:ccyc_addr_31_11 = 21'h02_0000 ; |
5'h12:ccyc_addr_31_11 = 21'h04_0000 ; |
5'h13:ccyc_addr_31_11 = 21'h08_0000 ; |
5'h14:ccyc_addr_31_11 = 21'h10_0000 ; |
default: ccyc_addr_31_11 = 21'h00_0000 ; |
endcase |
end |
end |
|
endmodule |
/verilog/pci_cbe_en_crit.v
0,0 → 1,82
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "cbe_en_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// this one is included in master state machine for CBE output enable driving |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_cbe_en_crit |
( |
pci_cbe_en_out, |
cbe_en_slow_in, |
cbe_en_keep_in, |
pci_stop_in, |
pci_trdy_in |
) ; |
|
output pci_cbe_en_out ; |
input cbe_en_slow_in, |
cbe_en_keep_in, |
pci_stop_in, |
pci_trdy_in ; |
|
assign pci_cbe_en_out = cbe_en_slow_in || cbe_en_keep_in && pci_stop_in && pci_trdy_in ; |
|
endmodule |
/verilog/pci_wb_decoder.v
0,0 → 1,167
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: decoder.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// - Tilen Novak, tilen@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// Tilen Novak, tilen@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_wb_decoder (hit, addr_out, addr_in, base_addr, mask_addr, tran_addr, at_en) ; |
|
// Decoding address size parameter - for FPGAs 1MegByte is recommended |
// MAXIMUM is 20 (4KBytes), length 12 is 1 MByte !!! |
parameter decode_len = 12 ; |
|
//########################################################################################################### |
// ALL COMMENTS are written as there were decode_len 20. This number and 12 (32 - 20) are assigning the |
// numbers of decoded and compared bits, etc. |
//########################################################################################################### |
|
/*----------------------------------------------------------------------------------------------------------- |
DECODER interface decodes input address (ADDR_IN); what means that it validates (HIT), if input address |
falls within the defined image space boundaries. Image space boundarie is defined with image base address |
register (BASE_ADDR) and address mask register (MASK_ADDR). |
Beside that, it also translates (maps) the input address to the output address (ADDR_OUT), regarding the |
translation address register (TRAN_ADDR) and the address mask register. |
-----------------------------------------------------------------------------------------------------------*/ |
|
// output control |
output hit ; |
// output address |
output [31:0] addr_out ; |
// input address |
input [31:0] addr_in ; |
|
// input registers - 12 LSbits are not valid since the smallest possible size is 4KB ! |
input [31:(32-decode_len)] base_addr ; |
input [31:(32-decode_len)] mask_addr ; |
input [31:(32-decode_len)] tran_addr ; |
|
// input bit[2] of the Image Control register used to enable the address translation ! |
input at_en ; |
/*----------------------------------------------------------------------------------------------------------- |
Internal signals ! |
-----------------------------------------------------------------------------------------------------------*/ |
|
// bit[31] if address mask register is IMAGE ENABLE bit (img_en) |
wire img_en ; |
|
// addr_in_compare are masked input address bits that are compared with masked base_addr |
wire [31:(32-decode_len)] addr_in_compare ; |
// base_addr_compare are masked base address bits that are compared with masked addr_in |
wire [31:(32-decode_len)] base_addr_compare ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Decoding the input address! |
This logic produces the loghest path in this module! |
|
20 MSbits of input addres are as well as base address (20 bits) masked with corrected address mask. Only |
masked bits of each vector are actually logically compared. |
Bit[31] of address mask register is used to enable the image space ! |
-----------------------------------------------------------------------------------------------------------*/ |
|
assign addr_in_compare = (addr_in[31:(32-decode_len)] & mask_addr) ; |
|
assign base_addr_compare = (base_addr & mask_addr) ; |
|
assign img_en = mask_addr[31] ; |
|
assign hit = { 1'b1, addr_in_compare } == { img_en, base_addr_compare } ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Translating the input address! |
|
Translation of input address is not implemented if ADDR_TRAN_IMPL is not defined |
|
20 MSbits of input address are masked with negated value of the corrected address mask in order to get |
address bits of the input address which won't be replaced with translation address bits. |
Translation address bits (20 bits) are masked with corrected address mask. Only masked bits of vector are |
actually valid, all others are zero. |
Boath vectors are bit-wise ORed in order to get the valid translation address with an offset of an input |
address. |
12 LSbits of an input address are assigned to 12 LSbits of an output addres. |
-----------------------------------------------------------------------------------------------------------*/ |
|
`ifdef ADDR_TRAN_IMPL |
// if Address Translation Enable bit is set, then translation address is used othervise input address is used! |
// addr_in_combine input address bits are not replaced with translation address! |
wire [31:(32-decode_len)] addr_in_combine ; |
// tran_addr_combine are masked and combined with addr_in_combine! |
reg [31:(32-decode_len)] tran_addr_combine ; |
|
assign addr_in_combine = (addr_in[31:(32-decode_len)] & ~mask_addr) ; |
always@(at_en or tran_addr or mask_addr or addr_in) |
begin |
if (at_en) |
begin |
tran_addr_combine <= (tran_addr & mask_addr) ; |
end |
else |
begin |
tran_addr_combine <= (addr_in[31:(32-decode_len)] & mask_addr) ; |
end |
end |
|
assign addr_out[31:(32-decode_len)] = addr_in_combine | tran_addr_combine ; |
assign addr_out[(31-decode_len):0] = addr_in [(31-decode_len):0] ; |
`else |
assign addr_out = addr_in ; |
`endif |
|
endmodule |
|
/verilog/pci_frame_en_crit.v
0,0 → 1,82
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "frame_en_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// This one is used in master state machine for frame output enable driving |
|
module pci_frame_en_crit |
( |
pci_frame_en_out, |
frame_en_slow_in, |
frame_en_keep_in, |
pci_stop_in, |
pci_trdy_in |
) ; |
|
output pci_frame_en_out ; |
input frame_en_slow_in, |
frame_en_keep_in, |
pci_stop_in, |
pci_trdy_in ; |
|
assign pci_frame_en_out = frame_en_slow_in || frame_en_keep_in && pci_stop_in && pci_trdy_in ; |
|
endmodule |
/verilog/pci_pci_decoder.v
0,0 → 1,198
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_decoder.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "pci_constants.v" |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_pci_decoder (hit, addr_out, |
addr_in, bc_in, |
base_addr, mask_addr, tran_addr, at_en, |
mem_io_space, mem_en, io_en) ; |
|
// Decoding address size parameter - for FPGAs 1MegByte is recommended |
// MAXIMUM is 20 (4KBytes), length 12 is 1 MByte !!! |
parameter decode_len = 12 ; |
|
//########################################################################################################### |
// ALL COMMENTS are written as there were decode_len 20. This number and 12 (32 - 20) are assigning the |
// numbers of decoded and compared bits, etc. |
//########################################################################################################### |
|
/*----------------------------------------------------------------------------------------------------------- |
DECODER interface decodes input address (ADDR_IN); what means that it validates (HIT), if input address |
falls within the defined image space boundaries. Image space boundarie is defined with image base address |
register (BASE_ADDR) and address mask register (MASK_ADDR). |
Beside that, it also translates (maps) the input address to the output address (ADDR_OUT), regarding the |
translation address register (TRAN_ADDR) and the address mask register. |
-----------------------------------------------------------------------------------------------------------*/ |
|
// output control |
output hit ; |
// output address |
output [31:0] addr_out ; |
// input address and bus command |
input [31:0] addr_in ; |
input [3:0] bc_in ; |
|
// input registers - 12 LSbits are not valid since the smallest possible size is 4KB ! |
input [31:(32-decode_len)] base_addr ; |
input [31:(32-decode_len)] mask_addr ; |
input [31:(32-decode_len)] tran_addr ; |
|
// input bit[2] of the Image Control register used to enable the address translation ! |
input at_en ; |
|
// memory or io space selection and its enable signals ! |
input mem_io_space ; |
input mem_en ; |
input io_en ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Internal signals ! |
-----------------------------------------------------------------------------------------------------------*/ |
|
// bit[31] if address mask register is IMAGE ENABLE bit (img_en) |
wire img_en ; |
|
// addr_in_compare are masked input address bits that are compared with masked base_addr |
wire [31:(32-decode_len)] addr_in_compare ; |
// base_addr_compare are masked base address bits that are compared with masked addr_in |
wire [31:(32-decode_len)] base_addr_compare ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Decoding the input address! |
This logic produces the loghest path in this module! |
|
20 MSbits of input addres are as well as base address (20 bits) masked with corrected address mask. Only |
masked bits of each vector are actually logically compared. |
Bit[31] of address mask register is used to enable the image space ! |
Because of PCI bus specifications, there is also the comparison of memory/io selection (mem_io_space) and |
its appropriate enable bit (mem_en / io_en). |
-----------------------------------------------------------------------------------------------------------*/ |
|
assign addr_in_compare = (addr_in[31:(32-decode_len)] & mask_addr) ; |
|
assign base_addr_compare = (base_addr & mask_addr) ; |
|
assign img_en = mask_addr[31] ; |
|
wire addr_hit = (addr_in_compare == base_addr_compare) ; |
|
wire space_hit = (!mem_io_space && mem_en && img_en) || (mem_io_space && io_en && img_en) ; |
|
reg bc_hit ; |
always@(bc_in or mem_io_space) |
begin // Allowed bus commands for accesses through IMAGEs to WB bus - BC_CONF_WRITE/READ are not used with address claim!!! |
case ( {bc_in[3:1], mem_io_space} ) |
4'b001_1, // BC_IO_READ or BC_IO_WRITE and IO space |
4'b011_0, // BC_MEM_READ or BC_MEM_WRITE and MEM space |
4'b110_0, // BC_MEM_READ_MUL and MEM space - BC_DUAL_ADDR_CYC must NOT be allowed! |
4'b111_0: // BC_MEM_READ_LN or BC_MEM_WRITE_INVAL and MEM space |
bc_hit <= 1'b1 ; |
default: |
bc_hit <= 1'b0 ; |
endcase |
end |
|
wire bc_forbid = bc_in[3] && bc_in[2] && !bc_in[1] && bc_in[0] ; // BC_DUAL_ADDR_CYC must NOT be allowed! |
|
|
assign hit = (addr_hit && space_hit && bc_hit && !bc_forbid) ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Translating the input address! |
|
Translation of input address is not implemented if ADDR_TRAN_IMPL is not defined |
|
20 MSbits of input address are masked with negated value of the corrected address mask in order to get |
address bits of the input address which won't be replaced with translation address bits. |
Translation address bits (20 bits) are masked with corrected address mask. Only masked bits of vector are |
actually valid, all others are zero. |
Boath vectors are bit-wise ORed in order to get the valid translation address with an offset of an input |
address. |
12 LSbits of an input address are assigned to 12 LSbits of an output addres. |
-----------------------------------------------------------------------------------------------------------*/ |
|
`ifdef ADDR_TRAN_IMPL |
// if Address Translation Enable bit is set, then translation address is used othervise input address is used! |
// addr_in_combine input address bits are not replaced with translation address! |
wire [31:(32-decode_len)] addr_in_combine ; |
// tran_addr_combine are masked and combined with addr_in_combine! |
reg [31:(32-decode_len)] tran_addr_combine ; |
|
assign addr_in_combine = (addr_in[31:(32-decode_len)] & ~mask_addr) ; |
always@(at_en or tran_addr or mask_addr or addr_in) |
begin |
if (at_en) |
begin |
tran_addr_combine <= (tran_addr & mask_addr) ; |
end |
else |
begin |
tran_addr_combine <= (addr_in[31:(32-decode_len)] & mask_addr) ; |
end |
end |
|
assign addr_out[31:(32-decode_len)] = (addr_in_combine | tran_addr_combine) ; |
assign addr_out[(31-decode_len):0] = addr_in [(31-decode_len):0] ; |
`else |
assign addr_out = addr_in ; |
`endif |
|
endmodule |
|
/verilog/pci_io_mux.v
0,0 → 1,842
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pci_io_mux.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:29 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// this module instantiates output flip flops for PCI interface and |
// some fanout downsizing logic because of heavily constrained PCI signals |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_io_mux |
( |
reset_in, |
clk_in, |
frame_in, |
frame_en_in, |
frame_load_in, |
irdy_in, |
irdy_en_in, |
devsel_in, |
devsel_en_in, |
trdy_in, |
trdy_en_in, |
stop_in, |
stop_en_in, |
master_load_in, |
master_load_on_transfer_in, |
target_load_in, |
target_load_on_transfer_in, |
cbe_in, |
cbe_en_in, |
mas_ad_in, |
tar_ad_in, |
|
par_in, |
par_en_in, |
perr_in, |
perr_en_in, |
serr_in, |
serr_en_in, |
|
req_in, |
|
mas_ad_en_in, |
tar_ad_en_in, |
tar_ad_en_reg_in, |
|
ad_en_out, |
frame_en_out, |
irdy_en_out, |
devsel_en_out, |
trdy_en_out, |
stop_en_out, |
cbe_en_out, |
|
frame_out, |
irdy_out, |
devsel_out, |
trdy_out, |
stop_out, |
cbe_out, |
ad_out, |
ad_load_out, |
ad_en_unregistered_out, |
|
par_out, |
par_en_out, |
perr_out, |
perr_en_out, |
serr_out, |
serr_en_out, |
|
req_out, |
req_en_out, |
pci_trdy_in, |
pci_irdy_in, |
pci_frame_in, |
pci_stop_in |
); |
|
input reset_in, clk_in ; |
|
input frame_in ; |
input frame_en_in ; |
input frame_load_in ; |
input irdy_in ; |
input irdy_en_in ; |
input devsel_in ; |
input devsel_en_in ; |
input trdy_in ; |
input trdy_en_in ; |
input stop_in ; |
input stop_en_in ; |
input master_load_in ; |
input target_load_in ; |
|
input [3:0] cbe_in ; |
input cbe_en_in ; |
input [31:0] mas_ad_in ; |
input [31:0] tar_ad_in ; |
|
input mas_ad_en_in ; |
input tar_ad_en_in ; |
input tar_ad_en_reg_in ; |
|
input par_in ; |
input par_en_in ; |
input perr_in ; |
input perr_en_in ; |
input serr_in ; |
input serr_en_in ; |
|
output frame_en_out ; |
output irdy_en_out ; |
output devsel_en_out ; |
output trdy_en_out ; |
output stop_en_out ; |
output [31:0] ad_en_out ; |
output [3:0] cbe_en_out ; |
|
output frame_out ; |
output irdy_out ; |
output devsel_out ; |
output trdy_out ; |
output stop_out ; |
output [3:0] cbe_out ; |
output [31:0] ad_out ; |
output ad_load_out ; |
output ad_en_unregistered_out ; |
|
output par_out ; |
output par_en_out ; |
output perr_out ; |
output perr_en_out ; |
output serr_out ; |
output serr_en_out ; |
|
input req_in ; |
|
output req_out ; |
output req_en_out ; |
|
input pci_trdy_in, |
pci_irdy_in, |
pci_frame_in, |
pci_stop_in ; |
|
input master_load_on_transfer_in ; |
input target_load_on_transfer_in ; |
|
wire [31:0] temp_ad = tar_ad_en_reg_in ? tar_ad_in : mas_ad_in ; |
|
wire ad_en_ctrl_low ; |
|
wire ad_en_ctrl_mlow ; |
|
wire ad_en_ctrl_mhigh ; |
|
wire ad_en_ctrl_high ; |
|
wire ad_enable_internal = mas_ad_en_in || tar_ad_en_in ; |
|
pci_io_mux_ad_en_crit ad_en_low_gen |
( |
.ad_en_in (ad_enable_internal), |
.pci_frame_in (pci_frame_in), |
.pci_trdy_in (pci_trdy_in), |
.pci_stop_in (pci_stop_in), |
.ad_en_out (ad_en_ctrl_low) |
); |
|
pci_io_mux_ad_en_crit ad_en_mlow_gen |
( |
.ad_en_in (ad_enable_internal), |
.pci_frame_in (pci_frame_in), |
.pci_trdy_in (pci_trdy_in), |
.pci_stop_in (pci_stop_in), |
.ad_en_out (ad_en_ctrl_mlow) |
); |
|
pci_io_mux_ad_en_crit ad_en_mhigh_gen |
( |
.ad_en_in (ad_enable_internal), |
.pci_frame_in (pci_frame_in), |
.pci_trdy_in (pci_trdy_in), |
.pci_stop_in (pci_stop_in), |
.ad_en_out (ad_en_ctrl_mhigh) |
); |
|
pci_io_mux_ad_en_crit ad_en_high_gen |
( |
.ad_en_in (ad_enable_internal), |
.pci_frame_in (pci_frame_in), |
.pci_trdy_in (pci_trdy_in), |
.pci_stop_in (pci_stop_in), |
.ad_en_out (ad_en_ctrl_high) |
); |
|
assign ad_en_unregistered_out = ad_en_ctrl_high ; |
|
wire load = master_load_in || target_load_in ; |
wire load_on_transfer = master_load_on_transfer_in || target_load_on_transfer_in ; |
|
wire ad_load_ctrl_low ; |
wire ad_load_ctrl_mlow ; |
wire ad_load_ctrl_mhigh ; |
wire ad_load_ctrl_high ; |
|
assign ad_load_out = ad_load_ctrl_high ; |
|
pci_io_mux_ad_load_crit ad_load_low_gen |
( |
.load_in(load), |
.load_on_transfer_in(load_on_transfer), |
.pci_irdy_in(pci_irdy_in), |
.pci_trdy_in(pci_trdy_in), |
.load_out(ad_load_ctrl_low) |
); |
|
pci_io_mux_ad_load_crit ad_load_mlow_gen |
( |
.load_in(load), |
.load_on_transfer_in(load_on_transfer), |
.pci_irdy_in(pci_irdy_in), |
.pci_trdy_in(pci_trdy_in), |
.load_out(ad_load_ctrl_mlow) |
); |
|
pci_io_mux_ad_load_crit ad_load_mhigh_gen |
( |
.load_in(load), |
.load_on_transfer_in(load_on_transfer), |
.pci_irdy_in(pci_irdy_in), |
.pci_trdy_in(pci_trdy_in), |
.load_out(ad_load_ctrl_mhigh) |
); |
|
pci_io_mux_ad_load_crit ad_load_high_gen |
( |
.load_in(load), |
.load_on_transfer_in(load_on_transfer), |
.pci_irdy_in(pci_irdy_in), |
.pci_trdy_in(pci_trdy_in), |
.load_out(ad_load_ctrl_high) |
); |
|
pci_out_reg ad_iob0 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_low ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[0] ) , |
.en_in ( ad_en_ctrl_low ) , |
.en_out ( ad_en_out[0] ), |
.dat_out ( ad_out[0] ) |
); |
|
pci_out_reg ad_iob1 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_low ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[1] ) , |
.en_in ( ad_en_ctrl_low ) , |
.en_out ( ad_en_out[1] ), |
.dat_out ( ad_out[1] ) |
); |
|
pci_out_reg ad_iob2 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_low ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[2] ) , |
.en_in ( ad_en_ctrl_low ) , |
.en_out ( ad_en_out[2] ), |
.dat_out ( ad_out[2] ) |
); |
|
pci_out_reg ad_iob3 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_low ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[3] ) , |
.en_in ( ad_en_ctrl_low ) , |
.en_out ( ad_en_out[3] ), |
.dat_out ( ad_out[3] ) |
); |
|
pci_out_reg ad_iob4 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_low ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[4] ) , |
.en_in ( ad_en_ctrl_low ) , |
.en_out ( ad_en_out[4] ), |
.dat_out ( ad_out[4] ) |
); |
|
pci_out_reg ad_iob5 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_low ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[5] ) , |
.en_in ( ad_en_ctrl_low ) , |
.en_out ( ad_en_out[5] ), |
.dat_out ( ad_out[5] ) |
); |
|
pci_out_reg ad_iob6 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_low ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[6] ) , |
.en_in ( ad_en_ctrl_low ) , |
.en_out ( ad_en_out[6] ), |
.dat_out ( ad_out[6] ) |
); |
|
pci_out_reg ad_iob7 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_low ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[7] ) , |
.en_in ( ad_en_ctrl_low ) , |
.en_out ( ad_en_out[7] ), |
.dat_out ( ad_out[7] ) |
); |
|
pci_out_reg ad_iob8 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mlow ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[8] ) , |
.en_in ( ad_en_ctrl_mlow ) , |
.en_out ( ad_en_out[8] ), |
.dat_out ( ad_out[8] ) |
); |
|
pci_out_reg ad_iob9 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mlow ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[9] ) , |
.en_in ( ad_en_ctrl_mlow ) , |
.en_out ( ad_en_out[9] ), |
.dat_out ( ad_out[9] ) |
); |
|
pci_out_reg ad_iob10 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mlow ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[10] ) , |
.en_in ( ad_en_ctrl_mlow ) , |
.en_out ( ad_en_out[10] ), |
.dat_out ( ad_out[10] ) |
); |
|
pci_out_reg ad_iob11 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mlow ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[11] ) , |
.en_in ( ad_en_ctrl_mlow ) , |
.en_out ( ad_en_out[11] ), |
.dat_out ( ad_out[11] ) |
); |
|
pci_out_reg ad_iob12 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mlow ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[12] ) , |
.en_in ( ad_en_ctrl_mlow ) , |
.en_out ( ad_en_out[12] ), |
.dat_out ( ad_out[12] ) |
); |
|
pci_out_reg ad_iob13 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mlow ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[13] ) , |
.en_in ( ad_en_ctrl_mlow ) , |
.en_out ( ad_en_out[13] ), |
.dat_out ( ad_out[13] ) |
); |
|
pci_out_reg ad_iob14 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mlow ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[14] ) , |
.en_in ( ad_en_ctrl_mlow ) , |
.en_out ( ad_en_out[14] ), |
.dat_out ( ad_out[14] ) |
); |
|
pci_out_reg ad_iob15 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mlow ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[15] ) , |
.en_in ( ad_en_ctrl_mlow ) , |
.en_out ( ad_en_out[15] ), |
.dat_out ( ad_out[15] ) |
); |
|
pci_out_reg ad_iob16 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mhigh ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[16] ) , |
.en_in ( ad_en_ctrl_mhigh ) , |
.en_out ( ad_en_out[16] ), |
.dat_out ( ad_out[16] ) |
); |
|
pci_out_reg ad_iob17 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mhigh ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[17] ) , |
.en_in ( ad_en_ctrl_mhigh ) , |
.en_out ( ad_en_out[17] ), |
.dat_out ( ad_out[17] ) |
); |
|
pci_out_reg ad_iob18 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mhigh ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[18] ) , |
.en_in ( ad_en_ctrl_mhigh ) , |
.en_out ( ad_en_out[18] ), |
.dat_out ( ad_out[18] ) |
); |
|
pci_out_reg ad_iob19 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mhigh ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[19] ) , |
.en_in ( ad_en_ctrl_mhigh ) , |
.en_out ( ad_en_out[19] ), |
.dat_out ( ad_out[19] ) |
); |
|
pci_out_reg ad_iob20 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mhigh ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[20] ) , |
.en_in ( ad_en_ctrl_mhigh ) , |
.en_out ( ad_en_out[20] ), |
.dat_out ( ad_out[20] ) |
); |
|
pci_out_reg ad_iob21 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mhigh ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[21] ) , |
.en_in ( ad_en_ctrl_mhigh ) , |
.en_out ( ad_en_out[21] ), |
.dat_out ( ad_out[21] ) |
); |
|
pci_out_reg ad_iob22 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mhigh ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[22] ) , |
.en_in ( ad_en_ctrl_mhigh ) , |
.en_out ( ad_en_out[22] ), |
.dat_out ( ad_out[22] ) |
); |
|
pci_out_reg ad_iob23 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_mhigh ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[23] ) , |
.en_in ( ad_en_ctrl_mhigh ) , |
.en_out ( ad_en_out[23] ), |
.dat_out ( ad_out[23] ) |
); |
|
pci_out_reg ad_iob24 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_high ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[24] ) , |
.en_in ( ad_en_ctrl_high ) , |
.en_out ( ad_en_out[24] ), |
.dat_out ( ad_out[24] ) |
); |
|
pci_out_reg ad_iob25 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_high ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[25] ) , |
.en_in ( ad_en_ctrl_high ) , |
.en_out ( ad_en_out[25] ), |
.dat_out ( ad_out[25] ) |
); |
|
pci_out_reg ad_iob26 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_high ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[26] ) , |
.en_in ( ad_en_ctrl_high ) , |
.en_out ( ad_en_out[26] ), |
.dat_out ( ad_out[26] ) |
); |
|
pci_out_reg ad_iob27 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_high ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[27] ) , |
.en_in ( ad_en_ctrl_high ) , |
.en_out ( ad_en_out[27] ), |
.dat_out ( ad_out[27] ) |
); |
|
pci_out_reg ad_iob28 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_high ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[28] ) , |
.en_in ( ad_en_ctrl_high ) , |
.en_out ( ad_en_out[28] ), |
.dat_out ( ad_out[28] ) |
); |
|
pci_out_reg ad_iob29 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_high ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[29] ) , |
.en_in ( ad_en_ctrl_high ) , |
.en_out ( ad_en_out[29] ), |
.dat_out ( ad_out[29] ) |
); |
|
pci_out_reg ad_iob30 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_high ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[30] ) , |
.en_in ( ad_en_ctrl_high ) , |
.en_out ( ad_en_out[30] ), |
.dat_out ( ad_out[30] ) |
); |
|
pci_out_reg ad_iob31 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( ad_load_ctrl_high ), |
.en_en_in ( 1'b1 ), |
.dat_in ( temp_ad[31] ) , |
.en_in ( ad_en_ctrl_high ) , |
.en_out ( ad_en_out[31] ), |
.dat_out ( ad_out[31] ) |
); |
|
wire [3:0] cbe_load_ctrl = {4{ master_load_in }} ; |
wire [3:0] cbe_en_ctrl = {4{ cbe_en_in }} ; |
|
pci_out_reg cbe_iob0 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( cbe_load_ctrl[0] ), |
.en_en_in ( 1'b1 ), |
.dat_in ( cbe_in[0] ) , |
.en_in ( cbe_en_ctrl[0] ) , |
.en_out ( cbe_en_out[0] ), |
.dat_out ( cbe_out[0] ) |
); |
|
pci_out_reg cbe_iob1 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( cbe_load_ctrl[1] ), |
.en_en_in ( 1'b1 ), |
.dat_in ( cbe_in[1] ) , |
.en_in ( cbe_en_ctrl[1] ) , |
.en_out ( cbe_en_out[1] ), |
.dat_out ( cbe_out[1] ) |
); |
|
pci_out_reg cbe_iob2 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( cbe_load_ctrl[2] ), |
.en_en_in ( 1'b1 ), |
.dat_in ( cbe_in[2] ) , |
.en_in ( cbe_en_ctrl[2] ) , |
.en_out ( cbe_en_out[2] ), |
.dat_out ( cbe_out[2] ) |
); |
|
pci_out_reg cbe_iob3 |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( cbe_load_ctrl[3] ), |
.en_en_in ( 1'b1 ), |
.dat_in ( cbe_in[3] ) , |
.en_in ( cbe_en_ctrl[3] ) , |
.en_out ( cbe_en_out[3] ), |
.dat_out ( cbe_out[3] ) |
); |
|
pci_out_reg frame_iob |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( frame_load_in ), |
.en_en_in ( 1'b1 ), |
.dat_in ( frame_in ) , |
.en_in ( frame_en_in ) , |
.en_out ( frame_en_out ), |
.dat_out ( frame_out ) |
); |
|
pci_out_reg irdy_iob |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( 1'b1 ), |
.en_en_in ( 1'b1 ), |
.dat_in ( irdy_in ) , |
.en_in ( irdy_en_in ) , |
.en_out ( irdy_en_out ), |
.dat_out ( irdy_out ) |
); |
|
pci_out_reg trdy_iob |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( 1'b1 ), |
.en_en_in ( 1'b1 ), |
.dat_in ( trdy_in ) , |
.en_in ( trdy_en_in ) , |
.en_out ( trdy_en_out ), |
.dat_out ( trdy_out ) |
); |
|
pci_out_reg stop_iob |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( 1'b1 ), |
.en_en_in ( 1'b1 ), |
.dat_in ( stop_in ) , |
.en_in ( stop_en_in ) , |
.en_out ( stop_en_out ), |
.dat_out ( stop_out ) |
); |
|
pci_out_reg devsel_iob |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( 1'b1 ), |
.en_en_in ( 1'b1 ), |
.dat_in ( devsel_in ) , |
.en_in ( devsel_en_in ) , |
.en_out ( devsel_en_out ), |
.dat_out ( devsel_out ) |
); |
|
pci_out_reg par_iob |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( 1'b1 ), |
.en_en_in ( 1'b1 ), |
.dat_in ( par_in ) , |
.en_in ( par_en_in ) , |
.en_out ( par_en_out ), |
.dat_out ( par_out ) |
); |
|
pci_out_reg perr_iob |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( 1'b1 ), |
.en_en_in ( 1'b1 ), |
.dat_in ( perr_in ) , |
.en_in ( perr_en_in ) , |
.en_out ( perr_en_out ), |
.dat_out ( perr_out ) |
); |
|
pci_out_reg serr_iob |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( 1'b1 ), |
.en_en_in ( 1'b1 ), |
.dat_in ( serr_in ) , |
.en_in ( serr_en_in ) , |
.en_out ( serr_en_out ), |
.dat_out ( serr_out ) |
); |
|
pci_out_reg req_iob |
( |
.reset_in ( reset_in ), |
.clk_in ( clk_in) , |
.dat_en_in ( 1'b1 ), |
.en_en_in ( 1'b1 ), |
.dat_in ( req_in ) , |
.en_in ( 1'b1 ) , |
.en_out ( req_en_out ), |
.dat_out ( req_out ) |
); |
|
endmodule |
/verilog/pci_mas_ch_state_crit.v
0,0 → 1,82
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "mas_ch_state_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// Module is used in master state machine for state machine clock enable driving |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_mas_ch_state_crit |
( |
change_state_out, |
ch_state_med_in, |
sm_data_phases_in, |
pci_trdy_in, |
pci_stop_in |
) ; |
|
output change_state_out ; |
input ch_state_med_in, |
sm_data_phases_in, |
pci_trdy_in, |
pci_stop_in ; |
|
assign change_state_out = ch_state_med_in || sm_data_phases_in && (~(pci_trdy_in && pci_stop_in)) ; |
|
endmodule |
/verilog/pci_io_mux_ad_load_crit.v
0,0 → 1,74
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pci_io_mux_ad_load_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2002/02/01 14:43:31 mihad |
// *** empty log message *** |
// |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// module is provided for last level of logic for loading AD output flip-flops |
// and output backup flip - flops |
module pci_io_mux_ad_load_crit |
( |
load_in, |
load_on_transfer_in, |
pci_irdy_in, |
pci_trdy_in, |
load_out |
); |
|
input load_in, |
load_on_transfer_in, |
pci_irdy_in, |
pci_trdy_in ; |
|
output load_out ; |
|
assign load_out = load_in || (load_on_transfer_in && ~pci_irdy_in && ~pci_trdy_in) ; |
|
endmodule |
/verilog/pci_frame_load_crit.v
0,0 → 1,81
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "frame_load_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// This one is used in master state machine for frame output flip flop clock enable driving |
module pci_frame_load_crit |
( |
pci_frame_load_out, |
sm_data_phases_in, |
frame_load_slow_in, |
pci_trdy_in, |
pci_stop_in |
) ; |
|
output pci_frame_load_out ; |
input sm_data_phases_in, |
frame_load_slow_in, |
pci_trdy_in, |
pci_stop_in ; |
|
assign pci_frame_load_out = frame_load_slow_in || sm_data_phases_in && (~(pci_trdy_in && pci_stop_in)) ; |
|
endmodule |
/verilog/pci_cur_out_reg.v
0,0 → 1,268
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "cur_out_reg.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "pci_constants.v" |
|
// module is only a backup copy of relevant output registers |
// used in some arhitectures that support IOB registers, which have to have a |
// fanout of 1 |
// Otherwise nothing special in this module |
module pci_cur_out_reg |
( |
reset_in, |
clk_in, |
frame_in, |
frame_load_in, |
irdy_in, |
devsel_in, |
trdy_in, |
trdy_en_in, |
stop_in, |
ad_load_in, |
cbe_in, |
cbe_en_in, |
mas_ad_in, |
tar_ad_in, |
frame_en_in, |
irdy_en_in, |
|
mas_ad_en_in, |
tar_ad_en_in, |
ad_en_unregistered_in, |
|
par_in, |
par_en_in, |
perr_in, |
perr_en_in, |
serr_in, |
serr_en_in, |
|
frame_out, |
irdy_out, |
devsel_out, |
trdy_out, |
stop_out, |
cbe_out, |
cbe_en_out, |
ad_out, |
frame_en_out, |
irdy_en_out, |
ad_en_out, |
mas_ad_en_out, |
tar_ad_en_out, |
trdy_en_out, |
|
par_out, |
par_en_out, |
perr_out, |
perr_en_out, |
serr_out, |
serr_en_out |
) ; |
|
input reset_in, clk_in ; |
|
input frame_in ; |
input frame_load_in ; |
input irdy_in ; |
input devsel_in ; |
input trdy_in ; |
input stop_in ; |
input ad_load_in ; |
|
input [3:0] cbe_in ; |
input cbe_en_in ; |
input [31:0] mas_ad_in ; |
input [31:0] tar_ad_in ; |
|
input mas_ad_en_in ; |
input tar_ad_en_in ; |
input ad_en_unregistered_in ; |
|
input frame_en_in, |
irdy_en_in ; |
|
input trdy_en_in ; |
|
input par_in ; |
input par_en_in ; |
input perr_in ; |
input perr_en_in ; |
input serr_in ; |
input serr_en_in ; |
|
output frame_out ; |
reg frame_out ; |
output irdy_out ; |
reg irdy_out ; |
output devsel_out ; |
reg devsel_out ; |
output trdy_out ; |
reg trdy_out ; |
output stop_out ; |
reg stop_out ; |
output [3:0] cbe_out ; |
reg [3:0] cbe_out ; |
output [31:0] ad_out ; |
reg [31:0] ad_out ; |
|
output frame_en_out, |
irdy_en_out, |
ad_en_out, |
cbe_en_out, |
mas_ad_en_out, |
tar_ad_en_out, |
trdy_en_out ; |
|
reg frame_en_out, |
irdy_en_out, |
cbe_en_out, |
mas_ad_en_out, |
tar_ad_en_out, |
trdy_en_out; |
|
output par_out ; |
output par_en_out ; |
output perr_out ; |
output perr_en_out ; |
output serr_out ; |
output serr_en_out ; |
|
reg par_out ; |
reg par_en_out ; |
reg perr_out ; |
reg perr_en_out ; |
reg serr_out ; |
reg serr_en_out ; |
|
assign ad_en_out = mas_ad_en_out || tar_ad_en_out ; |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
begin |
irdy_out <= #`FF_DELAY 1'b1 ; |
devsel_out <= #`FF_DELAY 1'b1 ; |
trdy_out <= #`FF_DELAY 1'b1 ; |
stop_out <= #`FF_DELAY 1'b1 ; |
frame_en_out <= #`FF_DELAY 1'b0 ; |
irdy_en_out <= #`FF_DELAY 1'b0 ; |
mas_ad_en_out<= #`FF_DELAY 1'b0 ; |
tar_ad_en_out<= #`FF_DELAY 1'b0 ; |
trdy_en_out <= #`FF_DELAY 1'b0 ; |
par_out <= #`FF_DELAY 1'b0 ; |
par_en_out <= #`FF_DELAY 1'b0 ; |
perr_out <= #`FF_DELAY 1'b1 ; |
perr_en_out <= #`FF_DELAY 1'b0 ; |
serr_out <= #`FF_DELAY 1'b1 ; |
serr_en_out <= #`FF_DELAY 1'b0 ; |
cbe_en_out <= #`FF_DELAY 1'b0 ; |
|
end |
else |
begin |
irdy_out <= #`FF_DELAY irdy_in ; |
devsel_out <= #`FF_DELAY devsel_in ; |
trdy_out <= #`FF_DELAY trdy_in ; |
stop_out <= #`FF_DELAY stop_in ; |
frame_en_out <= #`FF_DELAY frame_en_in ; |
irdy_en_out <= #`FF_DELAY irdy_en_in ; |
mas_ad_en_out<= #`FF_DELAY mas_ad_en_in && ad_en_unregistered_in ; |
tar_ad_en_out<= #`FF_DELAY tar_ad_en_in && ad_en_unregistered_in ; |
trdy_en_out <= #`FF_DELAY trdy_en_in ; |
|
par_out <= #`FF_DELAY par_in ; |
par_en_out <= #`FF_DELAY par_en_in ; |
perr_out <= #`FF_DELAY perr_in ; |
perr_en_out <= #`FF_DELAY perr_en_in ; |
serr_out <= #`FF_DELAY serr_in ; |
serr_en_out <= #`FF_DELAY serr_en_in ; |
cbe_en_out <= #`FF_DELAY cbe_en_in ; |
end |
end |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
cbe_out <= #`FF_DELAY 4'hF ; |
else if ( ad_load_in ) |
cbe_out <= #`FF_DELAY cbe_in ; |
|
end |
|
wire [31:0] ad_source = tar_ad_en_out ? tar_ad_in : mas_ad_in ; |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
ad_out <= #`FF_DELAY 32'h0000_0000 ; |
else if ( ad_load_in ) |
ad_out <= #`FF_DELAY ad_source ; |
|
end |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
frame_out <= #`FF_DELAY 1'b1 ; |
else if ( frame_load_in ) |
frame_out <= #`FF_DELAY frame_in ; |
|
end |
|
endmodule |
/verilog/pci_target32_trdy_crit.v
0,0 → 1,86
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_target32_trdy_crit.v //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:13 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:30 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
module pci_target32_trdy_crit |
( |
trdy_w, |
trdy_w_frm, |
trdy_w_frm_irdy, |
pci_frame_in, |
pci_irdy_in, |
pci_trdy_out |
); |
|
input trdy_w ; // trdy signal (composed without critical signals) that do not need critical inputs |
input trdy_w_frm ; // trdy signal (composed without critical signals) that needs AND with critical FRAME input |
input trdy_w_frm_irdy ; // trdy signal (composed without critical signals) that needs AND with critical FRAME and |
// IRDY inputs |
input pci_frame_in ; // critical constrained input signal |
input pci_irdy_in ; // critical constrained input signal |
|
output pci_trdy_out ; // PCI trdy output |
|
// PCI trdy output with preserved hierarchy for minimum delay! |
assign pci_trdy_out = ~(trdy_w || (trdy_w_frm && ~pci_frame_in) || (trdy_w_frm_irdy && ~pci_frame_in && pci_irdy_in)) ; |
|
|
endmodule |
/verilog/pci_irdy_out_crit.v
0,0 → 1,82
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "irdy_out_crit.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// module is used to separate logic which uses criticaly constrained inputs from slower logic. |
// It is used to synthesize critical timing logic separately with faster cells or without optimization |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// This module is used in master state machine for IRDY output driving |
|
module pci_irdy_out_crit |
( |
pci_irdy_out, |
irdy_slow_in, |
pci_frame_out_in, |
pci_trdy_in, |
pci_stop_in |
) ; |
|
output pci_irdy_out ; |
input irdy_slow_in, |
pci_frame_out_in, |
pci_trdy_in, |
pci_stop_in ; |
|
assign pci_irdy_out = irdy_slow_in || (pci_frame_out_in && ~(pci_trdy_in && pci_stop_in)) ; |
|
endmodule |
/verilog/meta_flop.v
0,0 → 1,81
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "meta_flop.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
// this module is just an ordinary flip-flop - used for identifying meta stable critical flip flops - similar to synchronizer flop |
module meta_flop |
( |
rst_i, |
clk_i, |
ld_i, |
ld_val_i, |
en_i, |
d_i, |
meta_q_o |
) ; |
|
parameter p_reset_value = 0 ; |
|
input rst_i, |
clk_i, |
ld_i, |
ld_val_i, |
en_i, |
d_i ; |
|
output meta_q_o ; |
reg meta_q_o ; |
|
always@(posedge rst_i or posedge clk_i) |
begin |
if (rst_i) |
meta_q_o <= #1 p_reset_value ; |
else if (ld_i) |
meta_q_o <= #1 ld_val_i ; |
else if (en_i) |
meta_q_o <= #1 d_i ; |
end |
|
endmodule |
/verilog/bus_commands.v
0,0 → 1,77
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "bus_commands.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README.pdf //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/01 15:25:12 mihad |
// Repaired a few bugs, updated specification, added test bench files and design document |
// |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// definitions of PCI bus commands | used by PCI Master | used by PCI Target |
`define BC_IACK 4'h0 // yes no |
`define BC_SPECIAL 4'h1 // no no |
`define BC_IO_READ 4'h2 // yes yes |
`define BC_IO_WRITE 4'h3 // yes yes |
`define BC_RESERVED0 4'h4 // no no |
`define BC_RESERVED1 4'h5 // no no |
`define BC_MEM_READ 4'h6 // yes yes |
`define BC_MEM_WRITE 4'h7 // yes yes |
`define BC_RESERVED2 4'h8 // no no |
`define BC_RESERVED3 4'h9 // no no |
`define BC_CONF_READ 4'hA // yes yes |
`define BC_CONF_WRITE 4'hB // yes yes |
`define BC_MEM_READ_MUL 4'hC // yes yes |
`define BC_DUAL_ADDR_CYC 4'hD // no no |
`define BC_MEM_READ_LN 4'hE // yes yes |
`define BC_MEM_WRITE_INVAL 4'hF // no yes |
|
// common bits for configuration cycle commands |
`define BC_CONF_RW 3'b101 |
// common bits for io cycle commands |
`define BC_IO_RW 3'b001 |
/verilog/pci_ram_16x40d.v
0,0 → 1,96
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Xilinx architecture distributed RAM instantiation //// |
//// //// |
//// This file is part of pci bridge project //// |
//// http://www.opencores.org/cvsweb.shtml/pci/ //// |
//// //// |
//// Description //// |
//// Module instantiates 40 16x1D RAMs, to form 40 bit wide, //// |
//// 16 locations synchronous RAM to use in PCI Fifo instances //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc, mihad@opencores.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// |
module pci_ram_16x40d (data_out, we, data_in, read_address, write_address, wclk); |
parameter addr_width = 4 ; |
output [39:0] data_out; |
input we, wclk; |
input [39:0] data_in; |
input [addr_width - 1:0] write_address, read_address; |
|
wire [3:0] waddr = write_address ; |
wire [3:0] raddr = read_address ; |
|
RAM16X1D ram00 (.DPO(data_out[0]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[0]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram01 (.DPO(data_out[1]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[1]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram02 (.DPO(data_out[2]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[2]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram03 (.DPO(data_out[3]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[3]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram04 (.DPO(data_out[4]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[4]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram05 (.DPO(data_out[5]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[5]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram06 (.DPO(data_out[6]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[6]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram07 (.DPO(data_out[7]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[7]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram08 (.DPO(data_out[8]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[8]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram09 (.DPO(data_out[9]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[9]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram10 (.DPO(data_out[10]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[10]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram11 (.DPO(data_out[11]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[11]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram12 (.DPO(data_out[12]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[12]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram13 (.DPO(data_out[13]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[13]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram14 (.DPO(data_out[14]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[14]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram15 (.DPO(data_out[15]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[15]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram16 (.DPO(data_out[16]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[16]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram17 (.DPO(data_out[17]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[17]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram18 (.DPO(data_out[18]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[18]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram19 (.DPO(data_out[19]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[19]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram20 (.DPO(data_out[20]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[20]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram21 (.DPO(data_out[21]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[21]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram22 (.DPO(data_out[22]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[22]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram23 (.DPO(data_out[23]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[23]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram24 (.DPO(data_out[24]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[24]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram25 (.DPO(data_out[25]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[25]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram26 (.DPO(data_out[26]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[26]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram27 (.DPO(data_out[27]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[27]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram28 (.DPO(data_out[28]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[28]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram29 (.DPO(data_out[29]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[29]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram30 (.DPO(data_out[30]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[30]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram31 (.DPO(data_out[31]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[31]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram32 (.DPO(data_out[32]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[32]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram33 (.DPO(data_out[33]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[33]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram34 (.DPO(data_out[34]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[34]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram35 (.DPO(data_out[35]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[35]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram36 (.DPO(data_out[36]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[36]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram37 (.DPO(data_out[37]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[37]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram38 (.DPO(data_out[38]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[38]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
RAM16X1D ram39 (.DPO(data_out[39]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[39]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); |
endmodule |
/verilog/timescale.v
0,0 → 1,16
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "timescale.v" //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2001/10/05 08:11:22 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// |
|
// timescale directive is included in all core's modules for simulation purposes |
`timescale 1ns/1ps |
/verilog/pci_constants.v
0,0 → 1,160
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "pci_constants.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - Miha Dolenc (mihad@opencores.org) //// |
//// - Tadej Markovic (tadej@opencores.org) //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2001/10/05 08:14:28 mihad |
// Updated all files with inclusion of timescale file for simulation purposes. |
// |
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
|
// first include user definable parameters |
`ifdef REGRESSION // Used only for regression testing purposes!!! |
`include "pci_regression_constants.v" |
`else |
`include "pci_user_constants.v" |
`endif |
|
//////////////////////////////////////////////////////////////////////// |
//// //// |
//// FIFO parameters define behaviour of FIFO control logic and //// |
//// FIFO depths. //// |
//// //// |
//////////////////////////////////////////////////////////////////////// |
`define WBW_DEPTH (1 << `WBW_ADDR_LENGTH) |
`define WBR_DEPTH (1 << `WBR_ADDR_LENGTH) |
`define PCIW_DEPTH (1 << `PCIW_ADDR_LENGTH) |
`define PCIR_DEPTH (1 << `PCIR_ADDR_LENGTH) |
|
// defines on which bit in control bus means what |
`define ADDR_CTRL_BIT 3 |
`define LAST_CTRL_BIT 0 |
`define DATA_ERROR_CTRL_BIT 1 |
`define UNUSED_CTRL_BIT 2 |
`define BURST_BIT 2 |
|
// MAX Retry counter value for PCI Master state-machine |
// This value is 8-bit because of 8-bit retry counter !!! |
//`define PCI_RTY_CNT_MAX 8'h08 |
|
// Value of address mask for WB configuration image. This has to be defined always, since it is a value, that is not changable in runtime. |
// !!!!!!!!!!!!!!!!!!!!!!!If this is not defined, WB configuration access will not be possible!!!!!!!!!!!!!!!!!!!!!1 |
`define WB_AM0 20'hffff_f |
|
// PCI target & WB slave ADDRESS names for configuration space !!! |
// This does not include address offsets of PCI Header registers - they starts at offset 0 (see PCI spec.) |
// ALL VALUES are without 2 LSBits AND there is required that address bit [8] is set while |
// accessing this registers, otherwise the configuration header will be accessed !!! |
`define P_IMG_CTRL0_ADDR 6'h00 // Address offset = h 100 |
`define P_BA0_ADDR 6'h01 // Address offset = h 104 |
`define P_AM0_ADDR 6'h02 // Address offset = h 108 |
`define P_TA0_ADDR 6'h03 // Address offset = h 10c |
`define P_IMG_CTRL1_ADDR 6'h04 // Address offset = h 110 |
`define P_BA1_ADDR 6'h05 // Address offset = h 114 |
`define P_AM1_ADDR 6'h06 // Address offset = h 118 |
`define P_TA1_ADDR 6'h07 // Address offset = h 11c |
`define P_IMG_CTRL2_ADDR 6'h08 // Address offset = h 120 |
`define P_BA2_ADDR 6'h09 // Address offset = h 124 |
`define P_AM2_ADDR 6'h0a // Address offset = h 128 |
`define P_TA2_ADDR 6'h0b // Address offset = h 12c |
`define P_IMG_CTRL3_ADDR 6'h0c // Address offset = h 130 |
`define P_BA3_ADDR 6'h0d // Address offset = h 134 |
`define P_AM3_ADDR 6'h0e // Address offset = h 138 |
`define P_TA3_ADDR 6'h0f // Address offset = h 13c |
`define P_IMG_CTRL4_ADDR 6'h10 // Address offset = h 140 |
`define P_BA4_ADDR 6'h11 // Address offset = h 144 |
`define P_AM4_ADDR 6'h12 // Address offset = h 148 |
`define P_TA4_ADDR 6'h13 // Address offset = h 14c |
`define P_IMG_CTRL5_ADDR 6'h14 // Address offset = h 150 |
`define P_BA5_ADDR 6'h15 // Address offset = h 154 |
`define P_AM5_ADDR 6'h16 // Address offset = h 158 |
`define P_TA5_ADDR 6'h17 // Address offset = h 15c |
`define P_ERR_CS_ADDR 6'h18 // Address offset = h 160 |
`define P_ERR_ADDR_ADDR 6'h19 // Address offset = h 164 |
`define P_ERR_DATA_ADDR 6'h1a // Address offset = h 168 |
|
`define WB_CONF_SPC_BAR_ADDR 6'h20 // Address offset = h 180 |
`define W_IMG_CTRL1_ADDR 6'h21 // Address offset = h 184 |
`define W_BA1_ADDR 6'h22 // Address offset = h 188 |
`define W_AM1_ADDR 6'h23 // Address offset = h 18c |
`define W_TA1_ADDR 6'h24 // Address offset = h 190 |
`define W_IMG_CTRL2_ADDR 6'h25 // Address offset = h 194 |
`define W_BA2_ADDR 6'h26 // Address offset = h 198 |
`define W_AM2_ADDR 6'h27 // Address offset = h 19c |
`define W_TA2_ADDR 6'h28 // Address offset = h 1a0 |
`define W_IMG_CTRL3_ADDR 6'h29 // Address offset = h 1a4 |
`define W_BA3_ADDR 6'h2a // Address offset = h 1a8 |
`define W_AM3_ADDR 6'h2b // Address offset = h 1ac |
`define W_TA3_ADDR 6'h2c // Address offset = h 1b0 |
`define W_IMG_CTRL4_ADDR 6'h2d // Address offset = h 1b4 |
`define W_BA4_ADDR 6'h2e // Address offset = h 1b8 |
`define W_AM4_ADDR 6'h2f // Address offset = h 1bc |
`define W_TA4_ADDR 6'h30 // Address offset = h 1c0 |
`define W_IMG_CTRL5_ADDR 6'h31 // Address offset = h 1c4 |
`define W_BA5_ADDR 6'h32 // Address offset = h 1c8 |
`define W_AM5_ADDR 6'h33 // Address offset = h 1cc |
`define W_TA5_ADDR 6'h34 // Address offset = h 1d0 |
`define W_ERR_CS_ADDR 6'h35 // Address offset = h 1d4 |
`define W_ERR_ADDR_ADDR 6'h36 // Address offset = h 1d8 |
`define W_ERR_DATA_ADDR 6'h37 // Address offset = h 1dc |
`define CNF_ADDR_ADDR 6'h38 // Address offset = h 1e0 |
// Following two registers are not implemented in a configuration space but in a WishBone unit! |
`define CNF_DATA_ADDR 6'h39 // Address offset = h 1e4 |
`define INT_ACK_ADDR 6'h3a // Address offset = h 1e8 |
// ------------------------------------- |
`define ICR_ADDR 6'h3b // Address offset = h 1ec |
`define ISR_ADDR 6'h3c // Address offset = h 1f0 |
|
`ifdef PCI33 |
`define HEADER_66MHz 1'b0 |
`else |
`ifdef PCI66 |
`define HEADER_66MHz 1'b1 |
`endif |
`endif |
|
// all flip-flops in the design have this inter-assignment delay |
`define FF_DELAY 1 |
|