URL
https://opencores.org/ocsvn/pci/pci/trunk
Subversion Repositories pci
Compare Revisions
- This comparison shows the changes necessary to convert path
/pci/tags/working_demo/rtl
- from Rev 8 to Rev 154
- ↔ Reverse comparison
Rev 8 → Rev 154
/verilog/wbw_wbr_fifos.v
0,0 → 1,570
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "timescale.v" |
|
module 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, |
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 |
) ; |
|
/*----------------------------------------------------------------------------------------------------------- |
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 ; |
|
// 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 ; |
|
/*----------------------------------------------------------------------------------------------------------- |
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 ; |
|
// obvious |
wire vcc = 1'b1 ; |
wire gnd = 1'b0 ; |
|
/*----------------------------------------------------------------------------------------------------------- |
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 ; |
|
/*----------------------------------------------------------------------------------------------------------- |
FlipFlops for indicating if complete delayed read completion is present in the FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
/*reg wbr_inTransactionCount ; |
reg wbr_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 wbr_last_in = wbr_wallow && wbr_control_in[`LAST_CTRL_BIT] ; |
wire wbr_last_out = wbr_rallow && wbr_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 |
wire wbr_clear = reset_in || wbr_flush_in ; // WBR_FIFO clear |
|
`ifdef FPGA |
/*----------------------------------------------------------------------------------------------------------- |
this code is included only for FPGA core usage - somewhat different logic because of sharing |
one block selectRAM+ between two FIFOs |
-----------------------------------------------------------------------------------------------------------*/ |
`ifdef BIG |
/*----------------------------------------------------------------------------------------------------------- |
Big FPGAs |
WBW_FIFO and WBR_FIFO address prefixes - used for extending read and write addresses because of varible |
FIFO depth and fixed SelectRAM+ size. Addresses are zero paded on the left to form long enough address |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(7 - WBW_ADDR_LENGTH):0] wbw_addr_prefix = {( 8 - WBW_ADDR_LENGTH){1'b0}} ; |
wire [(7 - WBR_ADDR_LENGTH):0] wbr_addr_prefix = {( 8 - WBR_ADDR_LENGTH){1'b0}} ; |
|
// compose addresses |
wire [7:0] wbw_whole_waddr = {wbw_addr_prefix, wbw_waddr} ; |
wire [7:0] wbw_whole_raddr = {wbw_addr_prefix, wbw_raddr} ; |
|
wire [7:0] wbr_whole_waddr = {wbr_addr_prefix, wbr_waddr} ; |
wire [7:0] wbr_whole_raddr = {wbr_addr_prefix, wbr_raddr} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Only 8 bits out of 16 are used in ram3 and ram6 - wires for referencing them |
-----------------------------------------------------------------------------------------------------------*/ |
wire [15:0] dpram3_portB_output ; |
wire [15:0] dpram6_portA_output ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Control out assignements from ram3 output |
-----------------------------------------------------------------------------------------------------------*/ |
assign wbw_control_out = dpram3_portB_output[15:12] ; |
assign wbr_control_out = dpram6_portA_output[15:12] ; |
|
assign wbw_cbe_out = dpram3_portB_output[3:0] ; |
assign wbr_be_out = dpram6_portA_output[3:0] ; |
|
wire wbw_read_enable = 1'b1 ; |
wire wbr_read_enable = 1'b1 ; |
|
// Block SelectRAM+ cells instantiation |
RAMB4_S16_S16 dpram16_1 (.ADDRA(wbw_whole_waddr), .DIA(wbw_addr_data_in[15:0]), |
.ENA(vcc), .RSTA(reset_in), |
.CLKA(wb_clock_in), .WEA(wbw_wallow), |
.DOA(), |
.ADDRB(wbw_whole_raddr), .DIB(16'h0000), |
.ENB(wbw_read_enable), .RSTB(reset_in), |
.CLKB(pci_clock_in), .WEB(gnd), |
.DOB(wbw_addr_data_out[15:0])) ; |
|
RAMB4_S16_S16 dpram16_2 (.ADDRA(wbw_whole_waddr), .DIA(wbw_addr_data_in[31:16]), |
.ENA(vcc), .RSTA(reset_in), |
.CLKA(wb_clock_in), .WEA(wbw_wallow), |
.DOA(), |
.ADDRB(wbw_whole_raddr), .DIB(16'h0000), |
.ENB(wbw_read_enable), .RSTB(reset_in), |
.CLKB(pci_clock_in), .WEB(gnd), |
.DOB(wbw_addr_data_out[31:16])) ; |
|
RAMB4_S16_S16 dpram16_3 (.ADDRA(wbw_whole_waddr), .DIA({wbw_control_in, 8'h00, wbw_cbe_in}), |
.ENA(vcc), .RSTA(reset_in), |
.CLKA(wb_clock_in), .WEA(wbw_wallow), |
.DOA(), |
.ADDRB(wbw_whole_raddr), .DIB(16'h0000), |
.ENB(wbw_read_enable), .RSTB(reset_in), |
.CLKB(pci_clock_in), .WEB(gnd), |
.DOB(dpram3_portB_output)) ; |
|
RAMB4_S16_S16 dpram16_4 (.ADDRA(wbr_whole_raddr), .DIA(16'h0000), |
.ENA(1'b1), .RSTA(reset_in), |
.CLKA(wb_clock_in), .WEA(gnd), |
.DOA(wbr_data_out[15:0]), |
.ADDRB(wbr_whole_waddr), .DIB(wbr_data_in[15:0]), |
.ENB(wbr_read_enable), .RSTB(reset_in), |
.CLKB(pci_clock_in), .WEB(wbr_wallow), |
.DOB()) ; |
|
RAMB4_S16_S16 dpram16_5 (.ADDRA(wbr_whole_raddr), .DIA(16'h0000), |
.ENA(1'b1), .RSTA(reset_in), |
.CLKA(wb_clock_in), .WEA(gnd), |
.DOA(wbr_data_out[31:16]), |
.ADDRB(wbr_whole_waddr), .DIB(wbr_data_in[31:16]), |
.ENB(wbr_read_enable), .RSTB(reset_in), |
.CLKB(pci_clock_in), .WEB(wbr_wallow), |
.DOB()) ; |
|
RAMB4_S16_S16 dpram16_6 (.ADDRA(wbr_whole_raddr), .DIA(16'h0000), |
.ENA(1'b1), .RSTA(reset_in), |
.CLKA(wb_clock_in), .WEA(gnd), |
.DOA(dpram6_portA_output), |
.ADDRB(wbr_whole_waddr), .DIB({wbr_control_in, 8'h00, wbr_be_in}), |
.ENB(wbr_read_enable), .RSTB(reset_in), |
.CLKB(pci_clock_in), .WEB(wbr_wallow), |
.DOB()) ; |
|
`else // SMALL FPGAs |
|
/*----------------------------------------------------------------------------------------------------------- |
Small FPGAs |
WBW_FIFO and WBR_FIFO address prefixes - used for extending read and write addresses because of varible |
FIFO depth and fixed SelectRAM+ size. Addresses are always paded, because of RAM sharing between FIFOs |
WBW addresses are zero padded on the left, WBR addresses are padded |
with ones on the left |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(7 - WBW_ADDR_LENGTH):0] wbw_addr_prefix = {( 8 - WBW_ADDR_LENGTH){1'b0}} ; |
wire [(7 - WBR_ADDR_LENGTH):0] wbr_addr_prefix = {( 8 - WBR_ADDR_LENGTH){1'b1}} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Only 8 bits out of 16 are used in ram3 - wires for referencing them |
-----------------------------------------------------------------------------------------------------------*/ |
wire [15:0] dpram3_portA_output ; |
wire [15:0] dpram3_portB_output ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Control out assignements from ram3 output |
-----------------------------------------------------------------------------------------------------------*/ |
assign wbw_control_out = dpram3_portB_output[15:12] ; |
assign wbr_control_out = dpram3_portA_output[15:12] ; |
|
assign wbw_cbe_out = dpram3_portB_output[3:0] ; |
assign wbr_be_out = dpram3_portA_output[3:0] ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Port A address generation for block SelectRam+ in SpartanII or Virtex |
Port A is clocked by WISHBONE clock, DIA is input for wbw_fifo, DOA is output for wbr_fifo. Address is multiplexed |
between two values. |
Address multiplexing: |
wbw_wenable == 1 => ADDRA = wbw_waddr (write pointer of WBW_FIFO) |
else ADDRA = wbr_raddr (read pointer of WBR_FIFO) |
-----------------------------------------------------------------------------------------------------------*/ |
wire [7:0] portA_addr = wbw_wallow ? {wbw_addr_prefix, wbw_waddr} : {wbr_addr_prefix, wbr_raddr} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Port B address generation for block SelectRam+ in SpartanII or Virtex |
Port B is clocked by PCI clock, DIB is input for wbr_fifo, DOB is output for wbw_fifo. Address is multiplexed |
between two values. |
Address multiplexing: |
wbr_wenable == 1 => ADDRB = wbr_waddr (write pointer of WBR_FIFO) |
else ADDRB = wbw_raddr (read pointer of WBW_FIFO) |
-----------------------------------------------------------------------------------------------------------*/ |
wire [7: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 ; |
|
// Block SelectRAM+ cells instantiation |
RAMB4_S16_S16 dpram16_1 (.ADDRA(portA_addr), .DIA(wbw_addr_data_in[15:0]), |
.ENA(portA_enable), .RSTA(reset_in), |
.CLKA(wb_clock_in), .WEA(wbw_wallow), |
.DOA(wbr_data_out[15:0]), |
.ADDRB(portB_addr), .DIB(wbr_data_in[15:0]), |
.ENB(portB_enable), .RSTB(reset_in), |
.CLKB(pci_clock_in), .WEB(wbr_wallow), |
.DOB(wbw_addr_data_out[15:0])) ; |
|
RAMB4_S16_S16 dpram16_2 (.ADDRA(portA_addr), .DIA(wbw_addr_data_in[31:16]), |
.ENA(portA_enable), .RSTA(reset_in), |
.CLKA(wb_clock_in), .WEA(wbw_wallow), |
.DOA(wbr_data_out[31:16]), |
.ADDRB(portB_addr), .DIB(wbr_data_in[31:16]), |
.ENB(portB_enable), .RSTB(reset_in), |
.CLKB(pci_clock_in), .WEB(wbr_wallow), |
.DOB(wbw_addr_data_out[31:16])) ; |
|
RAMB4_S16_S16 dpram16_3 (.ADDRA(portA_addr), .DIA({wbw_control_in, 8'h00, wbw_cbe_in}), |
.ENA(portA_enable), .RSTA(reset_in), |
.CLKA(wb_clock_in), .WEA(wbw_wallow), |
.DOA(dpram3_portA_output), |
.ADDRB(portB_addr), .DIB({wbr_control_in, 8'h00, wbr_be_in}), |
.ENB(portB_enable), .RSTB(reset_in), |
.CLKB(pci_clock_in), .WEB(wbr_wallow), |
.DOB(dpram3_portB_output)) ; |
`endif |
|
|
|
|
|
`else |
wire [39:0] wbw_ram_data_out ; |
wire [39:0] wbw_ram_data_in = {wbw_control_in, wbw_cbe_in, wbw_addr_data_in} ; |
wire [39:0] wbr_ram_data_in = {wbr_control_in, wbr_be_in, wbr_data_in} ; |
wire [39:0] wbr_ram_data_out ; |
assign wbw_control_out = wbw_ram_data_out[39:36] ; |
assign wbw_cbe_out = wbw_ram_data_out[35:32] ; |
assign wbw_addr_data_out = wbw_ram_data_out [31:0] ; |
|
assign wbr_control_out = wbr_ram_data_out[39:36] ; |
assign wbr_be_out = wbr_ram_data_out[35:32] ; |
assign wbr_data_out = wbr_ram_data_out [31:0] ; |
|
`ifdef SYNCHRONOUS |
/*----------------------------------------------------------------------------------------------------------- |
ASIC memory primitives will be added here in the near future - currently there is only some generic, |
behavioral dual port ram here |
-----------------------------------------------------------------------------------------------------------*/ |
DP_SRAM #(WBW_ADDR_LENGTH, WBW_DEPTH) wbw_ram (.reset_in(reset_in), .wclock_in(wb_clock_in), .rclock_in(pci_clock_in), .data_in(wbw_ram_data_in), |
.raddr_in(wbw_raddr), .waddr_in(wbw_waddr), .data_out(wbw_ram_data_out), .renable_in(1'b1), .wenable_in(wbw_wallow)); |
|
DP_SRAM #(WBR_ADDR_LENGTH, WBR_DEPTH) wbr_ram (.reset_in(reset_in), .wclock_in(pci_clock_in), .rclock_in(wb_clock_in), .data_in(wbr_ram_data_in), |
.raddr_in(wbr_raddr), .waddr_in(wbr_waddr), .data_out(wbr_ram_data_out), .renable_in(1'b1), .wenable_in(wbr_wallow)); |
|
`else //ASYNCHRONOUS RAM |
DP_ASYNC_RAM #(WBW_ADDR_LENGTH, WBW_DEPTH) wbw_ram (.reset_in(reset_in), .wclock_in(wb_clock_in), .data_in(wbw_ram_data_in), |
.raddr_in(wbw_raddr), .waddr_in(wbw_waddr), .data_out(wbw_ram_data_out), .wenable_in(wbw_wallow)); |
|
DP_ASYNC_RAM #(WBR_ADDR_LENGTH, WBR_DEPTH) wbr_ram (.reset_in(reset_in), .wclock_in(pci_clock_in), .data_in(wbr_ram_data_in), |
.raddr_in(wbr_raddr), .waddr_in(wbr_waddr), .data_out(wbr_ram_data_out), .wenable_in(wbr_wallow)); |
`endif |
`endif |
|
/*----------------------------------------------------------------------------------------------------------- |
Instantiation of two control logic modules - one for WBW_FIFO and one for WBR_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
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)); |
|
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]} ; |
|
wire in_count_en = wbw_wallow && wbw_last_in ; |
wire out_count_en = wbw_renable_in && wbw_last_out ; |
|
always@(posedge wb_clock_in or posedge wbw_clear) |
begin |
if (wbw_clear) |
begin |
inGreyCount[(WBW_ADDR_LENGTH-2)] <= #`FF_DELAY 1'b1 ; |
inGreyCount[(WBW_ADDR_LENGTH-3):0] <= #`FF_DELAY {(WBW_ADDR_LENGTH-2),1'b0} ; |
end |
else |
if (in_count_en) |
inGreyCount <= #`FF_DELAY inNextGreyCount ; |
end |
|
always@(posedge pci_clock_in or posedge wbw_clear) |
begin |
if (wbw_clear) |
begin |
outGreyCount[(WBW_ADDR_LENGTH-2)] <= #`FF_DELAY 1'b1 ; |
outGreyCount[(WBW_ADDR_LENGTH-3):0] <= #`FF_DELAY {(WBW_ADDR_LENGTH-2),1'b0} ; |
end |
else |
if (out_count_en) |
outGreyCount <= #`FF_DELAY outNextGreyCount ; |
end |
|
always@(posedge wb_clock_in or posedge wbw_clear) |
begin |
if (wbw_clear) |
wbw_inTransactionCount <= #`FF_DELAY {(WBW_ADDR_LENGTH-1){1'b0}} ; |
else |
if (in_count_en) |
wbw_inTransactionCount <= #`FF_DELAY wbw_inTransactionCount + 1'b1 ; |
end |
|
always@(posedge pci_clock_in or posedge wbw_clear) |
begin |
if (wbw_clear) |
wbw_outTransactionCount <= #`FF_DELAY {(WBW_ADDR_LENGTH-1){1'b0}} ; |
else |
if (out_count_en) |
wbw_outTransactionCount <= #`FF_DELAY wbw_outTransactionCount + 1'b1 ; |
end |
|
/*always@(posedge pci_clock_in or posedge wbr_clear) |
begin |
if (wbr_clear) |
wbr_inTransactionCount <= #`FF_DELAY 1'b0 ; |
else |
if (wbr_last_in && wbr_wallow) |
wbr_inTransactionCount <= #`FF_DELAY ~wbr_inTransactionCount ; |
end |
|
always@(posedge wb_clock_in or posedge wbr_clear) |
begin |
if (wbr_clear) |
wbr_outTransactionCount <= #`FF_DELAY 1'b0 ; |
else |
if (wbr_last_out) |
wbr_outTransactionCount <= #`FF_DELAY ~wbr_outTransactionCount ; |
end |
*/ |
|
// synchronize transaction ready output to reading clock |
reg wbw_transaction_ready_out ; |
always@(posedge pci_clock_in or posedge wbw_clear) |
begin |
if (wbw_clear) |
wbw_transaction_ready_out <= #`FF_DELAY 1'b0 ; |
else |
if ( out_count_en ) |
wbw_transaction_ready_out <= #`FF_DELAY 1'b0 ; |
else |
wbw_transaction_ready_out <= #`FF_DELAY inGreyCount != outGreyCount ; |
end |
|
endmodule |
|
/verilog/mas_ch_state_crit.v
0,0 → 1,73
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
`include "timescale.v" |
|
module 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/frame_crit.v
0,0 → 1,72
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
|
`include "timescale.v" |
|
// this one is used in master state machine for driving correct value of frame output |
|
module 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/perr_en_crit.v
0,0 → 1,91
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
`include "timescale.v" |
|
module 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/par_cbe_crit.v
0,0 → 1,73
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "par_cbe_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.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 cbe signals parity to include in overall parity calculation |
`include "timescale.v" |
|
module PAR_CBE_CRIT |
( |
par_cbe_include_out, |
par_cbe_out_in, |
par_cbe_en_in, |
pci_cbe_in |
) ; |
|
output par_cbe_include_out ; |
|
input par_cbe_out_in, |
par_cbe_en_in ; |
|
input [3:0] pci_cbe_in ; |
|
assign par_cbe_include_out = par_cbe_en_in ? par_cbe_out_in : ( pci_cbe_in[3] ^^ pci_cbe_in[2] ^^ pci_cbe_in[1] ^^ pci_cbe_in[0] ) ; |
|
endmodule |
/verilog/pci_target32_ctrl_en_crit.v
0,0 → 1,83
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_target32_ctrl_en_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.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 |
|
`include "constants.v" |
`include "timescale.v" |
|
module PCI_TARGET32_CTRL_EN_CRIT |
( |
ctrl_en_w, |
ctrl_en_w_irdy, |
pci_irdy_in, |
pci_trdy_en_out, |
pci_stop_en_out, |
pci_devsel_en_out |
); |
|
input ctrl_en_w ; // ctrl enable signal (composed without critical signals) that don't need critical IRDY input |
input ctrl_en_w_irdy ;// ctrl enable signal (composed without critical signals) that needs AND with critical IRDY input |
input pci_irdy_in ; // critical constrained input signal |
|
output pci_trdy_en_out ; // trdy enable output |
output pci_stop_en_out ; // stop enable output |
output pci_devsel_en_out ; // devsel enable output |
|
// control enable signal with preserved hierarchy for minimum delay! |
wire ctrl_en_out = (ctrl_en_w || (ctrl_en_w_irdy && ~pci_irdy_in)) ; |
|
// control enable signal assigned to all three outputs |
assign pci_trdy_en_out = ctrl_en_out ; |
assign pci_stop_en_out = ctrl_en_out ; |
assign pci_devsel_en_out = ctrl_en_out ; |
|
|
endmodule |
/verilog/synchronizer_flop.v
0,0 → 1,115
//=========================================================================== |
// $Id: synchronizer_flop.v,v 1.2 2001-10-05 08:14:30 mihad Exp $ |
// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 $ |
// Revision 1.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// Revision 1.5 2001/09/26 21:51:00 Tadej Markovic |
// Added parameter 'width', if module is used for e.g. bus |
// |
// Revision 1.4 2001/09/03 13:18:30 bbeaver |
// no message |
// |
// Revision 1.1 2001/09/03 11:16:00 Blue Beaver |
// no message |
// |
// Revision 1.1.1.1 2001/09/03 10:24:58 bbeaver |
// no message |
// |
// Revision 1.1 2001/09/02 11:32:03 Blue Beaver |
// no message |
// |
// |
|
`include "timescale.v" |
|
// If the vendor has a flop which is particularly good at settling out of |
// metastability, it should be used here. |
module synchronizer_flop ( |
data_in, clk_out, sync_data_out, async_reset |
); |
parameter width = 1 ; |
|
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 <= 0; |
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/fifo_control.v
0,0 → 1,448
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 "constants.v" |
`ifdef FPGA |
// fifo design in FPGA will be synchronous |
`ifdef SYNCHRONOUS |
`else |
`define SYNCHRONOUS |
`endif |
`endif |
|
`include "timescale.v" |
|
module FIFO_CONTROL |
( |
rclock_in, |
wclock_in, |
renable_in, |
wenable_in, |
reset_in, |
flush_in, |
almost_full_out, |
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 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 ; |
|
// 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_minus1 ; // one before current grey coded 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_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] ; |
|
// FFs for registered empty and full flags |
reg empty ; |
reg full ; |
|
// almost_empty and almost_full tag - implemented as latches |
reg almost_empty ; |
reg almost_full ; |
|
// 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 ; |
|
// almost full output assignment |
assign almost_full_out = almost_full && ~full ; |
|
// clear generation for FFs and registers |
wire clear = reset_in || flush_in ; |
|
`ifdef SYNCHRONOUS |
|
reg wclock_nempty_detect ; |
always@(posedge reset_in or posedge wclock_in) |
begin |
if (reset_in) |
wclock_nempty_detect <= #`FF_DELAY 1'b0 ; |
else |
wclock_nempty_detect <= #`FF_DELAY (rgrey_addr != wgrey_addr) ; |
end |
|
// special synchronizing mechanism for different implementations - in synchronous imp., empty is prolonged for 1 clock edge if no write clock comes after initial write |
reg stretched_empty ; |
always@(posedge rclock_in or posedge clear) |
begin |
if(clear) |
stretched_empty <= #`FF_DELAY 1'b1 ; |
else |
stretched_empty <= #`FF_DELAY empty && ~wclock_nempty_detect ; |
end |
|
// empty output is actual empty + 1 read clock cycle ( stretched empty ) |
assign empty_out = empty || stretched_empty ; |
|
//rallow generation |
assign rallow = renable_in && ~empty && ~stretched_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 && ~empty && ~stretched_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 = empty_out ? raddr : raddr_plus_one ; |
|
// enable for this register |
wire raddr_plus_one_en = rallow ; |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
raddr_plus_one[(ADDR_LENGTH - 1):1] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0}} ; |
raddr_plus_one[0] <= #`FF_DELAY 1'b1 ; |
end |
else if (raddr_plus_one_en) |
raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ; |
end |
|
// raddr is filled with raddr_plus_one on rising read clock edge when rallow is high |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
// initial value is 000......00 |
raddr <= #`FF_DELAY { ADDR_LENGTH{1'b0}} ; |
else if (rallow) |
raddr <= #`FF_DELAY raddr_plus_one ; |
end |
|
`else |
// asynchronous RAM storage for FIFOs - somewhat simpler control logic |
//rallow generation |
assign rallow = renable_in && ~empty ; |
|
assign rallow_out = rallow; |
|
assign almost_empty_out = almost_empty && ~empty ; |
|
// read address counter - normal counter, nothing to it |
// for asynchronous implementation, there is no need for pointing to next address. |
// On clock edge that read is performed, read address will change and on the next clock edge |
// asynchronous memory will provide next data |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
// initial value is 000......00 |
raddr <= #`FF_DELAY { ADDR_LENGTH{1'b0}} ; |
else if (rallow) |
raddr <= #`FF_DELAY raddr + 1'b1 ; |
end |
|
assign empty_out = empty ; |
assign raddr_out = raddr ; |
`endif |
|
/*----------------------------------------------------------------------------------------------- |
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 code register for two before read address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......010 |
rgrey_minus2[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_minus2[(ADDR_LENGTH - 2):2] <= #`FF_DELAY { (ADDR_LENGTH - 3){1'b0} } ; |
rgrey_minus2[1:0] <= #`FF_DELAY 2'b10 ; |
end |
else |
if (rallow) |
rgrey_minus2 <= #`FF_DELAY rgrey_minus1 ; |
end |
|
// grey code register for one before read address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......011 |
rgrey_minus1[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_minus1[(ADDR_LENGTH - 2):2] <= #`FF_DELAY { (ADDR_LENGTH - 3){1'b0} } ; |
rgrey_minus1[1:0] <= #`FF_DELAY 2'b11 ; |
end |
else |
if (rallow) |
rgrey_minus1 <= #`FF_DELAY rgrey_addr ; |
end |
|
// grey code register for read address - represents current Read Address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100.......01 |
rgrey_addr[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_addr[(ADDR_LENGTH - 2):1] <= #`FF_DELAY { (ADDR_LENGTH - 2){1'b0} } ; |
rgrey_addr[0] <= #`FF_DELAY 1'b1 ; |
end |
else |
if (rallow) |
rgrey_addr <= #`FF_DELAY rgrey_next ; |
end |
|
// grey code register for next read address - represents Grey Code of next read address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......00 |
rgrey_next[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_next[(ADDR_LENGTH - 2):0] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0} } ; |
end |
else |
if (rallow) |
rgrey_next <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ; |
end |
|
/*-------------------------------------------------------------------------------------------- |
Write address control consists of write address counter and three Grey Code Registers: |
- wgrey_minus1 represents Grey Coded address of location one before current write address |
- wgrey_addr represents current Grey Coded write address |
- wgrey_next represents Grey Coded next write address |
----------------------------------------------------------------------------------------------*/ |
// grey code register for one before write address |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100.....001 |
wgrey_minus1[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
wgrey_minus1[(ADDR_LENGTH - 2):2] <= #`FF_DELAY { (ADDR_LENGTH - 3){1'b0} } ; |
wgrey_minus1[1:0] <= #`FF_DELAY 2'b11 ; |
end |
else |
if (wallow) |
wgrey_minus1 <= #`FF_DELAY wgrey_addr ; |
end |
|
// grey code register for write address |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100.....001 |
wgrey_addr[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
wgrey_addr[(ADDR_LENGTH - 2):1] <= #`FF_DELAY { (ADDR_LENGTH - 2){1'b0} } ; |
wgrey_addr[0] <= #`FF_DELAY 1'b1 ; |
end |
else |
if (wallow) |
wgrey_addr <= #`FF_DELAY wgrey_next ; |
end |
|
// grey code register for next write address |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......00 |
wgrey_next[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
wgrey_next[(ADDR_LENGTH - 2):0] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0} } ; |
end |
else |
if (wallow) |
wgrey_next <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ; |
end |
|
// write address counter - nothing special |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
// initial value 00.........00 |
waddr <= #`FF_DELAY { (ADDR_LENGTH){1'b0} } ; |
else |
if (wallow) |
waddr <= #`FF_DELAY waddr + 1'b1 ; |
end |
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Registered full control: |
registered full is set on rising edge of wclock_in, when fifo is almost full and something gets written to it. |
It's kept high until something is read from FIFO, which is registered on next rising write clock edge. |
|
Registered almost full control: |
Almost full flag is set on rising write clock edge whenever two free locations are left in fifo and another entry is written to it. |
It remains set if nothing is read/written from/to fifo. All operations are synchronized on write clock. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
wire comb_full = wgrey_next == rgrey_addr ; |
wire comb_almost_full = wgrey_addr == rgrey_minus2 ; |
wire comb_two_left = wgrey_next == rgrey_minus2 ; |
|
//combinatorial input to Registered full FlipFlop |
wire reg_full = (wallow && comb_almost_full) || (comb_full) ; |
|
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
full <= #`FF_DELAY 1'b0 ; |
else |
full <= #`FF_DELAY reg_full ; |
end |
|
// input for almost full flip flop |
wire reg_almost_full_in = wallow && comb_two_left || comb_almost_full ; |
|
always@(posedge clear or posedge wclock_in) |
begin |
if (clear) |
almost_full <= #`FF_DELAY 1'b0 ; |
else |
almost_full <= #`FF_DELAY reg_almost_full_in ; |
end |
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Registered empty control: |
registered empty is set on rising edge of rclock_in when one location is occupied and read from it. It remains set until |
something is written to fifo which is detected on next read clock edge. |
|
Registered almost empty control: |
Almost empty is set on rising clock edge of read clock when two locations are used in fifo and one of them is read from it. |
It remains set until something is read/written from/to fifo. All operations are detected on rising edge of read clock. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
wire comb_almost_empty = rgrey_next == wgrey_addr ; |
wire comb_empty = rgrey_addr == wgrey_addr ; |
wire comb_two_used = rgrey_next == wgrey_minus1 ; |
|
// combinatorial input for registered emty FlipFlop |
wire reg_empty = (rallow && comb_almost_empty) || comb_empty ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
empty <= #`FF_DELAY 1'b1 ; |
else |
empty <= #`FF_DELAY reg_empty ; |
end |
|
// input for almost empty flip flop |
wire reg_almost_empty = rallow && comb_two_used || comb_almost_empty ; |
always@(posedge clear or posedge rclock_in) |
begin |
if (clear) |
almost_empty <= #`FF_DELAY 1'b0 ; |
else |
almost_empty <= #`FF_DELAY reg_almost_empty ; |
end |
|
endmodule |
/verilog/wb_master.v
0,0 → 1,952
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`define FSM_BITS 3 // number of bits needed for FSM states |
|
|
`include "bus_commands.v" |
`include "constants.v" |
`include "timescale.v" |
|
module 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_prefetch_en, |
pci_cache_line_size, |
wb_read_done, |
|
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_full_in, |
pcir_fifo_full_in, |
//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_set_in, |
pci_error_sig_out, |
pci_error_bc, |
write_rty_cnt_exp_out, |
read_rty_cnt_exp_out, |
|
CYC_O, |
STB_O, |
WE_O, |
SEL_O, |
ADR_O, |
MDATA_I, |
MDATA_O, |
ACK_I, |
RTY_I, |
ERR_I, |
CAB_O |
); |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Various parameters needed for state machine and other stuff |
----------------------------------------------------------------------------------------------------------------------*/ |
parameter S_IDLE = `FSM_BITS'h0 ; |
parameter S_WRITE = `FSM_BITS'h1 ; |
parameter S_WRITE_ERR_RTY = `FSM_BITS'h2 ; |
parameter S_READ = `FSM_BITS'h3 ; |
parameter S_READ_RTY = `FSM_BITS'h4 ; |
parameter S_TURN_ARROUND = `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_prefetch_en ; // pre-fetch enable for requested read from PCI Target |
input [7:0] pci_cache_line_size ; // CACHE line size register value for burst length |
output wb_read_done ; // read done and PCIR_FIFO has data ready |
|
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 |
input pcir_fifo_almost_full_in ; // almost full status indicator from PCIR_FIFO |
input pcir_fifo_full_in ; // full status indicator from PCIR_FIFO |
|
reg pcir_fifo_wenable_out ; |
reg [3:0] pcir_fifo_control_out ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
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 ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Control INPUT / OUTPUT signals for configuration space reporting registers !!! |
---------------------------------------------------------------------------------------------------------------------*/ |
input pci_error_sig_set_in ; // When error signaled bit in PCI_ERR_CS register is set |
output pci_error_sig_out ; // When error on WB bus occures |
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! |
|
reg pci_error_sig_out ; |
reg write_rty_cnt_exp_out ; |
reg read_rty_cnt_exp_out ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
WISHBONE bus interface signals - can be connected directly to WISHBONE bus |
---------------------------------------------------------------------------------------------------------------------*/ |
output CYC_O ; // cycle indicator output |
output STB_O ; // strobe output - data is valid when strobe and cycle indicator are high |
output WE_O ; // write enable output - 1 - write operation, 0 - read operation |
output [3:0] SEL_O ; // Byte select outputs |
output [31:0] ADR_O ; // WISHBONE address output |
input [31:0] MDATA_I ; // WISHBONE slave interface input data bus |
output [31:0] MDATA_O ; // WISHBONE slave interface output data bus |
input ACK_I ; // Acknowledge input - qualifies valid data on data output bus or received data on data input bus |
input RTY_I ; // retry input - signals from WISHBONE slave that cycle should be terminated and retried later |
input ERR_I ; // Signals from WISHBONE slave that access resulted in an error |
output CAB_O ; // consecutive address burst output - indicated that master will do a serial address transfer in current cycle |
|
reg [3:0] SEL_O ; |
|
|
/*########################################################################################################### |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
LOGIC, COUNTERS, STATE MACHINE and some control register bits |
============================================================= |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
###########################################################################################################*/ |
|
// wire for write attempt - 1 when PCI Target attempt to write and PCIW_FIFO has a write transaction ready |
wire w_attempt = ( pciw_fifo_transaction_ready_in && ~pciw_fifo_empty_in ) ; |
|
// 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 && ~pcir_fifo_full_in && 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_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@(pciw_fifo_control_in or pciw_fifo_almost_empty_in) |
begin |
// (pciw_fifo_control_in == `LAST) is the same as (pciw_fifo_control_in[0] == 1'b1) |
if (pciw_fifo_control_in[0] || pciw_fifo_almost_empty_in) // if last data is going to be transfered |
last_data_from_pciw_fifo <= 1'b1 ; // signal for last data from PCIW_FIFO |
else |
last_data_from_pciw_fifo <= 1'b0 ; |
end |
|
wire [7:0] cache_line_wire ; // wire assigned directly from cache_line register !!! |
// 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_prefetch_en or cache_line_wire or pcir_fifo_almost_full_in) |
begin |
case ({pci_tar_cmd, pci_tar_prefetch_en}) |
{`BC_IO_READ, 1'b0}, |
{`BC_IO_READ, 1'b1}, |
{`BC_MEM_READ, 1'b0} : |
begin // when single cycle |
last_data_to_pcir_fifo <= 1'b1 ; |
end |
{`BC_MEM_READ, 1'b1}, |
{`BC_MEM_READ_LN, 1'b0}, |
{`BC_MEM_READ_LN, 1'b1}, |
{`BC_MEM_READ_MUL, 1'b0} : |
begin // when burst cycle |
if ((cache_line_wire == 8'h1) || pcir_fifo_almost_full_in) |
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 (pcir_fifo_almost_full_in) |
last_data_to_pcir_fifo <= 1'b1 ; |
else |
last_data_to_pcir_fifo <= 1'b0 ; |
end |
default : |
begin |
last_data_to_pcir_fifo <= 1'b0 ; |
end |
endcase |
end |
|
reg [3:0] wb_no_response_cnt ; |
reg [3:0] wb_response_value ; |
reg wait_for_wb_response ; |
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 or ACK_I or ERR_I or RTY_I) |
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 (ACK_I || ERR_I || RTY_I) // if device responded, then ZERO must be written into counter |
wb_response_value <= 4'h0 ; |
else |
if (wait_for_wb_response) |
wb_response_value <= wb_no_response_cnt + 1 ; // count clocks when no response |
else |
wb_response_value <= wb_no_response_cnt ; |
set_retry <= 1'b0 ; |
end |
end |
|
wire retry = RTY_I || set_retry ; // retry signal - logic OR function between 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_max_value ; // signal tells when retry counter riches maximum value! |
reg reset_rty_cnt ; // signal for asynchronous reset of retry counter after each complete transfere |
reg last_data_transferred ; // signal is set by STATE MACHINE 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 <= 1'b1 ; // asynchronous set when reset signal is active |
else |
reset_rty_cnt <= ACK_I || ERR_I ; // synchronous set after completed transfere |
end |
|
// clock enable for retry counter - when there is sinchronous reset OR retry |
wire rty_cnt_clk_en = reset_rty_cnt || retry ; |
// data written into retry counter - ZEROS when sinchronous reset OR incremented value when retry |
wire [7:0] rty_cnt_data = reset_rty_cnt ? 8'h00 : rty_counter_in ; |
// 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 (rty_cnt_clk_en) |
rty_counter <= #`FF_DELAY rty_cnt_data ; // count-up or hold value depending on retry counter logic |
end |
end |
// Retry counter logic |
always@(rty_counter or rty_counter_in) |
begin |
if(rty_counter == `WB_RTY_CNT_MAX) // stop counting |
begin |
rty_counter_in <= rty_counter ; |
rty_counter_max_value <= 1'b1 ; |
end |
else |
begin |
rty_counter_in <= rty_counter_in + 1'b1 ; // count up |
rty_counter_max_value <= 1'b0 ; |
end |
end |
|
reg [7:0] cache_line ; // output from cache line down-counter |
reg [7:0] cache_line_in ; // input to cache line counter |
reg cache_line_into_cnt ; // control signal for loading cache line size to counter |
reg cache_line_count ; // control signal for count enable |
reg cache_line_reg_used ; // if pci_cache_line_size is ZERO then all PCIR_FIFO is read |
|
assign cache_line_wire = cache_line ; |
// cache line size down-counter register control |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) // reset counter |
cache_line <= #`FF_DELAY 8'h00 ; |
else |
cache_line <= #`FF_DELAY cache_line_in ; // count down or hold value depending on cache line counter logic |
end |
// cache line size down-counter logic |
always@(cache_line_into_cnt or cache_line_count or pci_cache_line_size or cache_line) |
begin |
if (cache_line_into_cnt) // load cache line size into counter |
begin |
if (pci_cache_line_size == 8'h0) |
cache_line_in = 8'h01 ; |
else |
cache_line_in = pci_cache_line_size ; |
end |
else |
if (cache_line_count) |
begin |
cache_line_in = cache_line - 1'h1 ; // count down |
end |
else |
begin |
cache_line_in = cache_line ; |
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_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 ; |
end |
else |
begin |
addr_cnt_out <= #`FF_DELAY addr_cnt_in ; // count up or hold value depending on cache line counter logic |
if (addr_into_cnt) |
bc_register <= #`FF_DELAY pciw_fifo_cbe_in ; |
end |
end |
// 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) |
begin |
if (addr_into_cnt) // load starting address into counter |
begin |
if (r_attempt) |
begin |
addr_cnt_in = pci_tar_address ; // if read request, then load read addresss from PCI Target |
end |
else |
begin |
addr_cnt_in = pciw_fifo_addr_data_in ; // if not read request, then load write address from PCIW_FIFO |
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 wb_stb_o ; // Internal signal for driwing STB_O on WB bus |
reg wb_we_o ; // Internal signal for driwing WE_O on WB bus |
reg wb_cyc_o ; // Internal signal for driwing CYC_O on WB bus and for enableing burst signal generation |
|
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 first_data_is_burst ; // Signal is set in S_WRITE or S_READ states, when data transfere is burst! |
reg burst_transfer ; // This signal is set when data transfere is burst and is reset with RESET or last data transfered |
|
// 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 ; |
end |
else |
begin |
retried <= #`FF_DELAY retried_d ; // delaying retried signal |
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_cmd or pci_tar_prefetch_en or pciw_fifo_control_in) |
begin |
if (addr_into_cnt) |
begin |
if (r_attempt) |
begin |
if (((pci_tar_cmd == `BC_MEM_READ) && pci_tar_prefetch_en) || |
(pci_tar_cmd == `BC_MEM_READ_LN) || |
(pci_tar_cmd == `BC_MEM_READ_MUL)) |
first_data_is_burst <= 1'b1 ; |
else |
first_data_is_burst <= 1'b0 ; |
end |
else |
begin |
// When first data is not LAST, then there will be burst transfere |
if (pciw_fifo_control_in[`BURST_BIT]) // (pciw_fifo_control_in != `LAST) |
first_data_is_burst <= 1'b1 ; |
else |
first_data_is_burst <= 1'b0 ; |
end |
end |
else |
first_data_is_burst <= 1'b0 ; |
end |
|
// clock enable for burst_transfere signal when last data is transfered OR if first data is burst |
wire burst_transfer_clk_en = last_data_transferred || first_data_is_burst ; |
// data written into burst_transfere register is ZERO when last data is transfered OR ONE when first data is burst |
wire burst_transfer_data = last_data_transferred ? 1'b0 : 1'b1 ; |
// FF for seting and reseting burst_transfere signal |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) |
burst_transfer <= #`FF_DELAY 1'b0 ; |
else |
begin |
if (burst_transfer_clk_en) |
burst_transfer <= #`FF_DELAY burst_transfer_data ; |
end |
end |
|
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) // reset state machine ti S_IDLE state |
c_state <= #`FF_DELAY S_IDLE ; |
else |
c_state <= #`FF_DELAY n_state ; |
end |
|
// state machine logic |
always@(c_state or |
ACK_I or |
RTY_I or |
ERR_I or |
w_attempt or |
r_attempt or |
pci_error_sig_set_in or |
retried or |
pciw_fifo_control_in or |
pciw_fifo_almost_empty_in or |
pci_tar_cmd or |
pci_tar_prefetch_en or |
cache_line or |
rty_counter or |
pci_tar_read_request or |
pcir_fifo_almost_full_in or |
rty_counter_max_value or |
last_data_to_pcir_fifo or |
first_wb_data_access or |
last_data_from_pciw_fifo |
) |
begin |
case (c_state) |
S_IDLE: |
begin |
// Default values for signals not used in this state |
pcir_fifo_wenable_out <= 1'b0 ; |
pcir_fifo_control_out <= 4'h0 ; |
addr_count <= 1'b0 ; |
cache_line_count <= 1'b0 ; |
pci_error_sig_out <= 1'b0 ; |
retried_d <= 1'b0 ; |
last_data_transferred <= 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 ERROR SIGNALED bit in pci_error_cs register is set, then state machine must be frozen |
case (pci_error_sig_set_in) |
1'b1 : |
begin |
pciw_fifo_renable_out <= 1'b0 ; |
addr_into_cnt <= 1'b0 ; |
cache_line_into_cnt <= 1'b0 ; |
n_state <= S_IDLE ; |
end |
default : |
begin |
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_out <= 1'b0 ; // the same data |
addr_into_cnt <= 1'b0 ; // the same address |
cache_line_into_cnt <= 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 |
pciw_fifo_renable_out <= 1'b1 ; // first location is address (in FIFO), next will be data |
addr_into_cnt <= 1'b1 ; // address must be latched into address counter |
cache_line_into_cnt <= 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 |
cache_line_into_cnt <= 1'b0 ; // cache line counter must not be changed for retried read |
pciw_fifo_renable_out <= 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 |
cache_line_into_cnt <= 1'b1 ; // cache line size must be latched into its counter |
pciw_fifo_renable_out <= 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_out <= 1'b0 ; |
addr_into_cnt <= 1'b0 ; |
cache_line_into_cnt <= 1'b0 ; |
n_state <= S_IDLE ; |
end |
endcase |
end |
endcase |
wb_stb_o <= 1'b0 ; |
wb_we_o <= 1'b0 ; |
wb_cyc_o <= 1'b0 ; |
end |
S_WRITE: // WRITE from PCIW_FIFO to WB bus |
begin |
// Default values for signals not used in this state |
pcir_fifo_wenable_out <= 1'b0 ; |
pcir_fifo_control_out <= 4'h0 ; |
addr_into_cnt <= 1'b0 ; |
cache_line_into_cnt <= 1'b0 ; |
cache_line_count <= 1'b0 ; |
wb_read_done <= 1'b0 ; |
read_rty_cnt_exp_out <= 1'b0 ; |
case ({ACK_I, ERR_I, RTY_I}) |
3'b100 : // If writting of one data is acknowledged |
begin |
pciw_fifo_renable_out <= 1'b1 ; // prepare next value (address when new trans., data when burst tran.) |
addr_count <= 1'b1 ; // prepare next address if there will be burst |
pci_error_sig_out <= 1'b0 ; // there was no error |
retried_d <= 1'b0 ; // there was no retry |
write_rty_cnt_exp_out <= 1'b0 ; // there was no retry |
wait_for_wb_response <= 1'b0 ; |
if (last_data_from_pciw_fifo) // if last data was transfered |
begin |
n_state <= S_IDLE ; |
last_data_transferred <= 1'b1 ; // signal for last data transfered |
end |
else |
begin |
n_state <= S_WRITE ; |
last_data_transferred <= 1'b0 ; |
end |
end |
3'b010 : // If writting of one data is terminated with ERROR |
begin |
pciw_fifo_renable_out <= 1'b1 ; // prepare next value (address when new trans., data when cleaning FIFO) |
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 |
write_rty_cnt_exp_out <= 1'b0 ; // there was no retry |
wait_for_wb_response <= 1'b0 ; |
if (last_data_from_pciw_fifo) // if last data was transfered |
n_state <= S_IDLE ; // go to S_IDLE 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 |
pciw_fifo_renable_out <= 1'b0 ; |
addr_count <= 1'b0 ; |
pci_error_sig_out <= 1'b0 ; |
last_data_transferred <= 1'b0 ; |
retried_d <= 1'b1 ; // there was a retry |
wait_for_wb_response <= 1'b0 ; |
if(rty_counter_max_value) // If retry counter reached maximum allowed value |
begin |
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 |
end |
else |
begin |
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 |
end |
end |
default : |
begin |
pciw_fifo_renable_out <= 1'b0 ; |
addr_count <= 1'b0 ; |
last_data_transferred <= 1'b0 ; |
retried_d <= 1'b0 ; |
wait_for_wb_response <= 1'b1 ; // wait for WB device to response (after 8 clocks RTY CNT is incremented) |
if(rty_counter_max_value) // when no WB response and RTY CNT reached maximum allowed value |
begin |
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 |
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 |
wb_stb_o <= 1'b1 ; |
wb_we_o <= 1'b1 ; |
wb_cyc_o <= 1'b1 ; |
end |
S_WRITE_ERR_RTY: // Clean current write transaction from PCIW_FIFO if ERROR or Retry counter expired occures |
begin |
pciw_fifo_renable_out <= 1'b1 ; // 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_out <= 1'b0 ; |
pcir_fifo_control_out <= 4'h0 ; |
addr_into_cnt <= 1'b0 ; |
cache_line_into_cnt <= 1'b0 ; |
cache_line_count <= 1'b0 ; |
addr_count <= 1'b0 ; |
pci_error_sig_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) |
n_state <= S_IDLE ; |
else |
n_state <= S_WRITE_ERR_RTY ; // Clean until last data is cleaned out from FIFO |
wb_stb_o <= 1'b0 ; |
wb_we_o <= 1'b0 ; |
wb_cyc_o <= 1'b0 ; |
end |
S_READ: // READ from WB bus to PCIR_FIFO |
begin |
// Default values for signals not used in this state |
pciw_fifo_renable_out <= 1'b0 ; |
addr_into_cnt <= 1'b0 ; |
cache_line_into_cnt <= 1'b0 ; |
pci_error_sig_out <= 1'b0 ; |
write_rty_cnt_exp_out <= 1'b0 ; |
case ({ACK_I, ERR_I, RTY_I}) |
3'b100 : // If reading of one data is acknowledged |
begin |
pcir_fifo_wenable_out <= 1'b1 ; // enable writting data into PCIR_FIFO |
addr_count <= 1'b1 ; // prepare next address if there will be burst |
cache_line_count <= 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_out <= `LAST ; // control code in FIFO must indicate LAST data transfered |
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_out <= 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_out <= 1'b1 ; // enable for writting to FIFO data with ERROR |
addr_count <= 1'b0 ; // no need for new address |
pcir_fifo_control_out <= `DATA_ERROR ; // control code in FIFO must indicate the DATA with ERROR |
last_data_transferred <= 1'b1 ; // signal for last data transfered |
wb_read_done <= 1'b1 ; // signal last data of read transaction for PCI Target |
cache_line_count <= 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_out <= 1'b0 ; |
pcir_fifo_control_out <= 4'h0 ; |
addr_count <= 1'b0 ; |
cache_line_count <= 1'b0 ; |
wait_for_wb_response <= 1'b0 ; |
case ({first_wb_data_access, rty_counter_max_value}) |
2'b10 : |
begin |
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 |
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 : |
begin |
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 ; |
cache_line_count <= 1'b0 ; |
read_rty_cnt_exp_out <= 1'b0 ; |
retried_d <= 1'b0 ; |
wait_for_wb_response <= 1'b1 ; // wait for WB device to response (after 8 clocks RTY CNT is incremented) |
if(rty_counter_max_value) // when no WB response and RTY CNT reached maximum allowed value |
begin |
n_state <= S_TURN_ARROUND ; // go here to stop read request |
pcir_fifo_wenable_out <= 1'b1 ; |
pcir_fifo_control_out <= `DATA_ERROR ; |
last_data_transferred <= 1'b1 ; |
wb_read_done <= 1'b1 ; |
end |
else |
begin |
n_state <= S_READ ; // stay in S_READ state to wait WB to response |
pcir_fifo_wenable_out <= 1'b0 ; |
pcir_fifo_control_out <= 4'h0 ; |
last_data_transferred <= 1'b0 ; |
wb_read_done <= 1'b0 ; |
end |
end |
endcase |
wb_stb_o <= 1'b1 ; |
wb_we_o <= 1'b0 ; |
wb_cyc_o <= 1'b1 ; |
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_out <= 1'b0 ; |
pcir_fifo_wenable_out <= 1'b0 ; |
pcir_fifo_control_out <= 4'h0 ; |
addr_into_cnt <= 1'b0 ; |
cache_line_into_cnt <= 1'b0 ; |
cache_line_count <= 1'b0 ; |
addr_count <= 1'b0 ; |
pci_error_sig_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 |
wb_stb_o <= 1'b0 ; |
wb_we_o <= 1'b0 ; |
wb_cyc_o <= 1'b0 ; |
end |
S_TURN_ARROUND: // Turn arround cycle after writting to PCIR_FIFO (for correct data when reading from PCIW_FIFO) |
begin |
// Default values for signals not used in this state |
pciw_fifo_renable_out <= 1'b0 ; |
pcir_fifo_wenable_out <= 1'b0 ; |
pcir_fifo_control_out <= 4'h0 ; |
addr_into_cnt <= 1'b0 ; |
cache_line_into_cnt <= 1'b0 ; |
cache_line_count <= 1'b0 ; |
addr_count <= 1'b0 ; |
pci_error_sig_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 ; |
wb_stb_o <= 1'b0 ; |
wb_we_o <= 1'b0 ; |
wb_cyc_o <= 1'b0 ; |
end |
default : |
begin |
// Default values for signals not used in this state |
pciw_fifo_renable_out <= 1'b0 ; |
pcir_fifo_wenable_out <= 1'b0 ; |
pcir_fifo_control_out <= 4'h0 ; |
addr_into_cnt <= 1'b0 ; |
cache_line_into_cnt <= 1'b0 ; |
cache_line_count <= 1'b0 ; |
addr_count <= 1'b0 ; |
pci_error_sig_out <= 1'b0 ; |
retried_d <= 1'b0 ; |
last_data_transferred <= 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 ; |
n_state <= S_IDLE ; |
wb_stb_o <= 1'b0 ; |
wb_we_o <= 1'b0 ; |
wb_cyc_o <= 1'b0 ; |
end |
endcase |
end |
|
// Signal for retry monitor in state machine when there is read and first (or single) data access |
wire ack_rty_response = ACK_I || RTY_I ; |
|
// clock enable for first_wb_data_access signal when NO WB cycle present OR there was acknowledge or retry termination |
wire wb_access_clk_en = ~wb_cyc_o || ack_rty_response ; |
// data written into first_wb_data_access signal register is ONE when no WB cycle present OR ZERO durin WB cycle (when |
// acknowledge or retry termination occures) |
wire wb_access_data = ~wb_cyc_o ? 1'b1 : 1'b0 ; |
// 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_access_clk_en) |
first_wb_data_access = wb_access_data ; |
end |
end |
|
|
// Signals to FIFO |
assign pcir_fifo_be_out = pci_tar_be ; |
assign pcir_fifo_data_out = MDATA_I ; |
|
// OUTPUT signals |
assign pci_error_bc = bc_register ; |
|
assign STB_O = wb_stb_o ; |
assign WE_O = wb_we_o ; |
assign CYC_O = wb_cyc_o ; |
assign CAB_O = wb_cyc_o & burst_transfer ; |
assign ADR_O = addr_cnt_out ; |
assign MDATA_O = pciw_fifo_addr_data_in ; |
|
always@(pciw_fifo_cbe_in or pci_tar_be or wb_we_o) |
begin |
if (wb_we_o) |
SEL_O = ~pciw_fifo_cbe_in ; |
else |
SEL_O = ~pci_tar_be ; |
end |
|
|
endmodule |
|
/verilog/dp_sram.v
0,0 → 1,94
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "dp_sram.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - mihad@opencores.org //// |
//// - Miha Dolenc //// |
//// //// |
//// All additional information is avaliable in the README.pdf //// |
//// 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.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// Revision 1.1 2001/08/06 18:12:43 mihad |
// Pocasi delamo kompletno zadevo |
// |
// |
|
`include "constants.v" |
`include "timescale.v" |
|
// behavioral syncronous read / syncronous write RAM |
module DP_SRAM(reset_in, wclock_in, rclock_in, data_in, raddr_in, waddr_in, data_out, renable_in, wenable_in); |
|
parameter ADDR_LENGTH = 7 ; |
parameter SIZE = 128 ; |
input reset_in ; |
input wclock_in ; |
input rclock_in ; |
input [39:0] data_in ; |
input [(ADDR_LENGTH - 1):0] raddr_in ; |
input [(ADDR_LENGTH - 1):0] waddr_in ; |
output [39:0] data_out ; |
input renable_in ; |
input wenable_in ; |
|
reg [39:0] mem [(SIZE - 1):0] ; |
wire [(ADDR_LENGTH - 1):0] raddr = raddr_in ; |
wire [(ADDR_LENGTH - 1):0] waddr = waddr_in ; |
|
reg [39:0] out_data ; |
|
assign data_out = out_data ; |
|
always@(posedge rclock_in or posedge reset_in) |
begin |
if(reset_in) |
out_data <= #`FF_DELAY 40'h0000000000 ; |
else if (renable_in) |
out_data <= #`FF_DELAY mem[raddr] ; |
end |
|
always@(posedge wclock_in) |
begin |
if (wenable_in) |
mem[waddr] <= #`FF_DELAY data_in ; |
end |
|
endmodule |
/verilog/pci_target32_sm.v
0,0 → 1,662
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`define FSM_BITS 2 // number of bits needed for FSM states |
|
|
`include "bus_commands.v" |
`include "constants.v" |
`include "timescale.v" |
|
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, |
pci_target_load_out, |
// address, data, bus command, byte enable in/outs |
pci_ad_reg_in, |
pci_ad_out, |
pci_ad_en_out, |
pci_cbe_reg_in, |
bckp_trdy_en_in, |
bckp_devsel_in, |
bckp_trdy_in, |
bckp_stop_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, |
req_out, |
rdy_out, |
addr_phase_out, |
bckp_trdy_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, |
target_abort_set_out, |
pciw_fifo_full_in, |
pcir_fifo_data_err_in, |
wbw_fifo_empty_in, |
wbu_frame_en_in |
|
) ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Various parameters needed for state machine and other stuff |
----------------------------------------------------------------------------------------------------------------------*/ |
parameter S_IDLE = `FSM_BITS'h0 ; |
parameter S_WAIT = `FSM_BITS'h1 ; |
parameter S_TRANSFERE = `FSM_BITS'h2 ; |
parameter S_BACKOFF = `FSM_BITS'h3 ; |
|
|
/*================================================================================================================== |
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 pci_target_load_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 bckp_trdy_en_in ; |
input bckp_devsel_in ; |
input bckp_trdy_in ; |
input bckp_stop_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 |
// 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_trdy_out ; // TRDY 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 with OR without 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 ; |
|
// Delayed frame signal for determining the address phase! |
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
previous_frame <= 1'b1 ; |
read_completed_reg <= 1'b0 ; |
disconect_wo_data_reg <= 1'b0 ; |
end |
else |
begin |
previous_frame <= pci_frame_reg_in ; |
read_completed_reg <= read_completed_in ; |
disconect_wo_data_reg <= disconect_wo_data_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) ; |
|
// 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])) ; |
|
// Signal for loadin 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 and read progresses are used for determining next state |
wire write_progress = ( |
(norm_access_to_config_in) || (read_completed_in && ~pciw_fifo_full_in) || |
(~read_processing_in && ~pciw_fifo_full_in) |
) ; |
wire read_progress = ((~read_completed_in && norm_access_to_config_in) || (read_completed_in && wbw_fifo_empty_in)) ; |
|
// Write allowed to PCIW_FIFO |
wire write_to_fifo = ((read_completed_in && ~pciw_fifo_full_in) || (~read_processing_in && ~pciw_fifo_full_in)) ; |
// Read allowed from PCIR_FIFO |
wire read_from_fifo = (read_completed_in && wbw_fifo_empty_in) ; |
// 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) ; |
|
// 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 norm_access_to_conf_reg ; |
reg same_read_reg ; |
reg cnf_progress ; |
reg addr_claim_reg ; |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
rw_cbe0 <= 1'b0 ; |
wr_progress <= 1'b0 ; |
rd_progress <= 1'b0 ; |
rd_from_fifo <= 1'b0 ; |
rd_request <= 1'b0 ; |
wr_to_fifo <= 1'b0 ; |
norm_access_to_conf_reg <= 1'b0 ; |
same_read_reg <= 1'b0 ; |
cnf_progress <= 1'b0 ; |
addr_claim_reg <= 1'b0 ; |
end |
else |
begin |
if (addr_phase) |
begin |
rw_cbe0 <= pci_cbe_reg_in[0] ; |
wr_progress <= write_progress ; |
rd_progress <= read_progress ; |
rd_from_fifo <= read_from_fifo ; |
rd_request <= read_request ; |
wr_to_fifo <= write_to_fifo ; |
norm_access_to_conf_reg <= norm_access_to_config_in ; |
same_read_reg <= same_read_in ; |
cnf_progress <= config_access ; |
addr_claim_reg <= addr_claim_in ; |
end |
end |
end |
|
// 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) || |
(~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_in) || |
(~rw_cbe0 && ~disconect_wo_data_in && ~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 state_transfere ; |
reg state_backoff ; |
reg state_default ; |
// 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), |
.disconect_wo_data_in (disconect_wo_data_in), |
.pcir_fifo_data_err_in (pcir_fifo_data_err_in), |
.rw_cbe0 (rw_cbe0), |
.pci_frame_in (pci_frame_in), |
.pci_irdy_in (pci_irdy_in), |
.state_wait (state_wait), |
.state_transfere (state_transfere), |
.state_backoff (state_backoff), |
.state_default (state_default), |
.clk_enable (pcit_sm_clk_en) |
); |
|
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 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 or |
s_wait_progress or |
s_tran_progress |
) |
begin |
case (c_state) |
S_IDLE : |
begin |
state_idle <= 1'b1 ; |
state_wait <= 1'b0 ; |
state_transfere <= 1'b0 ; |
state_backoff <= 1'b0 ; |
state_default <= 1'b0 ; |
n_state <= S_WAIT ; |
end |
S_WAIT : |
begin |
state_idle <= 1'b0 ; |
state_wait <= 1'b1 ; |
state_transfere <= 1'b0 ; |
state_backoff <= 1'b0 ; |
state_default <= 1'b0 ; |
if (s_wait_progress) |
n_state <= S_TRANSFERE ; |
else |
n_state <= S_BACKOFF ; |
end |
S_TRANSFERE : |
begin |
state_idle <= 1'b0 ; |
state_wait <= 1'b0 ; |
state_transfere <= 1'b1 ; |
state_backoff <= 1'b0 ; |
state_default <= 1'b0 ; |
if (s_tran_progress) |
n_state <= S_IDLE ; |
else |
n_state <= S_BACKOFF ; |
end |
S_BACKOFF : |
begin |
state_idle <= 1'b0 ; |
state_wait <= 1'b0 ; |
state_transfere <= 1'b0 ; |
state_backoff <= 1'b1 ; |
state_default <= 1'b0 ; |
n_state <= S_IDLE ; |
end |
default : |
begin |
state_idle <= 1'b0 ; |
state_wait <= 1'b0 ; |
state_transfere <= 1'b0 ; |
state_backoff <= 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) || |
(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 && ~disconect_wo_data_in) || |
(state_transfere && disconect_wo_data_in && pci_irdy_reg_in) || |
(state_transfere && ~rw_cbe0 && ~pcir_fifo_data_err_in) |
) ; |
// 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 = ( |
(state_transfere && disconect_wo_data_in) || |
(state_transfere && ~rw_cbe0 && pcir_fifo_data_err_in) || |
(state_backoff && ~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 && ~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_in) || |
(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) |
) ; |
// 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) |
); |
|
// if address is claimed when read |
// NO CRITICAL SIGNALS |
wire ad_en_w = ( |
(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) |
) ; |
// if read |
// MUST BE ANDED WITH CRITICAL ~FRAME |
wire ad_en_w_frm = ( |
(state_transfere && ~rw_cbe0) || |
(state_backoff && ~rw_cbe0) |
) ; |
// AD enable module used for preserving the architecture because of minimum delay for critical inputs |
PCI_TARGET32_AD_EN_CRIT pci_target_ad_enable_critical |
( |
.ad_en_w (ad_en_w), |
.ad_en_w_frm (ad_en_w_frm), |
.pci_frame_in (pci_frame_in), |
.pci_ad_en_out (pci_ad_en_out) |
); |
|
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_w = ( |
(~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) || |
(state_backoff && ~pci_frame_reg_in) |
) ; |
// if cycle is progressing |
// MUST BE ANDED WITH CRITICAL ~IRDY |
wire ctrl_en_w_irdy = ( |
(state_transfere) || |
(state_backoff) |
) ; |
// Clock enable module used for preserving the architecture because of minimum delay for critical inputs |
PCI_TARGET32_CTRL_EN_CRIT pci_target_control_enable_critical |
( |
.ctrl_en_w (ctrl_en_w), |
.ctrl_en_w_irdy (ctrl_en_w_irdy), |
.pci_irdy_in (pci_irdy_in), |
.pci_trdy_en_out (pci_trdy_en_out), |
.pci_stop_en_out (pci_stop_en_out), |
.pci_devsel_en_out (pci_devsel_en_out) |
); |
|
// 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 <= 1'b1 ; |
state_transfere_reg <= 1'b0 ; |
state_backoff_reg <= 1'b0 ; |
end |
else |
begin |
bckp_trdy_reg <= bckp_trdy_in ; |
state_transfere_reg <= state_transfere ; |
state_backoff_reg <= 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 && ~bckp_trdy_reg && ~cnf_progress && ~rw_cbe0 && same_read_reg && rd_from_fifo && ~pci_irdy_reg_in) |
) ; |
|
// NO CRITICAL SIGNALS |
wire tar_load_out_w = (state_wait) ; |
// MUST BE ANDED WITH CRITICAL ~IRDY |
wire tar_load_out_w_irdy = (bckp_trdy_en_in && ~rw_cbe0) ; |
// NO CRITICAL SIGNALS |
wire load_med_reg_w = ( |
(prepare_rd_fifo_data) || |
(state_wait && ~cnf_progress && ~rw_cbe0 && same_read_reg && rd_from_fifo && ~target_abort_in) |
) ; |
// MUST BE ANDED WITH CRITICAL ~IRDY |
wire load_med_reg_w_irdy = |
(bckp_trdy_en_in && ~bckp_trdy_in && ~cnf_progress && ~rw_cbe0 && same_read_reg && rd_from_fifo) ; |
// Clock enable module used for preserving the architecture because of minimum delay for critical inputs |
PCI_TARGET32_LOAD_CRIT pci_target_load_critical |
( |
.tar_load_out_w (tar_load_out_w), |
.tar_load_out_w_irdy (tar_load_out_w_irdy), |
.load_med_reg_w (load_med_reg_w), |
.load_med_reg_w_irdy (load_med_reg_w_irdy), |
.pci_irdy_in (pci_irdy_in), |
.pci_target_load_out (pci_target_load_out), |
.load_medium_reg_out (load_medium_reg_out) |
); |
|
assign sel_fifo_mreg_out = (~pci_irdy_reg_in && ~bckp_trdy_reg) ; |
|
assign sel_conf_fifo_out = (cnf_progress || norm_access_to_conf_reg) ; |
|
assign fetch_conf_out = ((cnf_progress || norm_access_to_conf_reg) && ~rw_cbe0 && ~bckp_devsel_in) ; |
|
// 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)) |
) ; |
|
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) |
) ; |
|
// 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_trdy_out = bckp_trdy_in ; |
assign target_abort_set_out = (bckp_devsel_in && bckp_trdy_in && ~bckp_stop_in) ; |
// request signal for delayed sinc. module |
assign req_out = (state_wait && ~cnf_progress && ~norm_access_to_conf_reg && ~rw_cbe0 && rd_request && ~target_abort_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 address_out = pci_ad_reg_in ; |
assign bc_out = pci_cbe_reg_in ; |
assign bc0_out = rw_cbe0 ; |
|
|
endmodule |
/verilog/mas_ad_en_crit.v
0,0 → 1,72
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
|
`include "timescale.v" |
// This module is used in master state machine for AD lines output enable driving |
module MAS_AD_EN_CRIT |
( |
pci_ad_en_out, |
ad_en_slow_in, |
ad_en_keep_in, |
pci_stop_in, |
pci_trdy_in |
) ; |
|
output pci_ad_en_out ; |
input ad_en_slow_in, |
ad_en_keep_in, |
pci_stop_in, |
pci_trdy_in ; |
|
assign pci_ad_en_out = ad_en_slow_in || ad_en_keep_in && pci_stop_in && pci_trdy_in ; |
|
endmodule |
/verilog/io_mux_load_mux.v
0,0 → 1,71
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "io_mux_load_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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// this module is provided for downsizing fanout of critical logic cells, which use heavily constrained |
// pci inputs - if target is driving ad lines it is also responsible for clock enables of output |
// flip flops - otherwise master controls clock enable of output flip flops. |
|
`include "timescale.v" |
|
module IO_MUX_LOAD_MUX |
( |
tar_ad_en_reg_in, |
mas_ad_load_in, |
tar_ad_load_in, |
ad_load_out |
); |
|
input tar_ad_en_reg_in ; |
input mas_ad_load_in ; |
input tar_ad_load_in ; |
output ad_load_out ; |
|
assign ad_load_out = tar_ad_en_reg_in ? tar_ad_load_in : mas_ad_load_in ; |
|
endmodule |
/verilog/pci_target32_devs_crit.v
0,0 → 1,79
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
|
`include "constants.v" |
`include "timescale.v" |
|
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/perr_crit.v
0,0 → 1,75
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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#) |
`include "timescale.v" |
|
module 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_io_mux.v
0,0 → 1,748
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
`include "constants.v" |
`include "timescale.v" |
|
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, |
target_load_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, |
|
par_out, |
par_en_out, |
perr_out, |
perr_en_out, |
serr_out, |
serr_en_out, |
|
req_out, |
req_en_out |
|
); |
|
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 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 ; |
|
|
wire [31:0] temp_ad = tar_ad_en_reg_in ? tar_ad_in : mas_ad_in ; |
|
wire ad_en_ctrl_low ; |
IO_MUX_EN_MULT ad_en_low_gen(.mas_ad_en_in(mas_ad_en_in), .tar_ad_en_in(tar_ad_en_in), .ad_en_out(ad_en_ctrl_low)) ; |
|
wire ad_en_ctrl_mlow ; |
IO_MUX_EN_MULT ad_en_mlow_gen(.mas_ad_en_in(mas_ad_en_in), .tar_ad_en_in(tar_ad_en_in), .ad_en_out(ad_en_ctrl_mlow)) ; |
|
wire ad_en_ctrl_mhigh ; |
IO_MUX_EN_MULT ad_en_mhigh_gen(.mas_ad_en_in(mas_ad_en_in), .tar_ad_en_in(tar_ad_en_in), .ad_en_out(ad_en_ctrl_mhigh)) ; |
|
wire ad_en_ctrl_high ; |
IO_MUX_EN_MULT ad_en_high_gen(.mas_ad_en_in(mas_ad_en_in), .tar_ad_en_in(tar_ad_en_in), .ad_en_out(ad_en_ctrl_high)) ; |
|
wire ad_load_ctrl_low ; |
IO_MUX_LOAD_MUX ad_load_low_gen(.tar_ad_en_reg_in(tar_ad_en_reg_in), .mas_ad_load_in(master_load_in), .tar_ad_load_in(target_load_in), .ad_load_out(ad_load_ctrl_low)); |
|
wire ad_load_ctrl_mlow ; |
IO_MUX_LOAD_MUX ad_load_mlow_gen(.tar_ad_en_reg_in(tar_ad_en_reg_in), .mas_ad_load_in(master_load_in), .tar_ad_load_in(target_load_in), .ad_load_out(ad_load_ctrl_mlow)); |
|
wire ad_load_ctrl_mhigh ; |
IO_MUX_LOAD_MUX ad_load_mhigh_gen(.tar_ad_en_reg_in(tar_ad_en_reg_in), .mas_ad_load_in(master_load_in), .tar_ad_load_in(target_load_in), .ad_load_out(ad_load_ctrl_mhigh)); |
|
wire ad_load_ctrl_high ; |
IO_MUX_LOAD_MUX ad_load_high_gen(.tar_ad_en_reg_in(tar_ad_en_reg_in), .mas_ad_load_in(master_load_in), .tar_ad_load_in(target_load_in), .ad_load_out(ad_load_ctrl_high)) ; |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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 }} ; |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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] ) |
); |
|
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 ) |
); |
|
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 ) |
); |
|
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 ) |
); |
|
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 ) |
); |
|
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 ) |
); |
|
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 ) |
); |
|
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 ) |
); |
|
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 ) |
); |
|
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/wb_addr_mux.v
0,0 → 1,357
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 "constants.v" |
`include "timescale.v" |
|
module WB_ADDR_MUX |
( |
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 GUEST |
// in guest bridge implementation configuration image can be taken out |
`ifdef WB_CNF_IMAGE |
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec0( |
.hit (hit[0]), |
.addr_out (addr0), |
.addr_in (address_in), |
.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 |
`else |
`ifdef HOST |
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec0( |
.hit (hit[0]), |
.addr_out (addr0), |
.addr_in (address_in), |
.base_addr (bar0_in), |
.mask_addr (am0_in), |
.tran_addr (ta0_in), |
.at_en (1'b0) |
) ; |
`endif |
`endif |
|
// one image is always implemented |
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec1( |
.hit (hit[1]), |
.addr_out (addr1), |
.addr_in (address_in), |
.base_addr (bar1_in), |
.mask_addr (am1_in), |
.tran_addr (ta1_in), |
.at_en (at_en_in[1]) |
) ; |
|
`ifdef WB_IMAGE2 |
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec2( |
.hit (hit[2]), |
.addr_out (addr2), |
.addr_in (address_in), |
.base_addr (bar2_in), |
.mask_addr (am2_in), |
.tran_addr (ta2_in), |
.at_en (at_en_in[2]) |
) ; |
|
assign hit[5:3] = 3'b000 ; |
assign addr3 = 32'h0000_0000 ; |
assign addr4 = 32'h0000_0000 ; |
assign addr5 = 32'h0000_0000 ; |
|
// address multiplexer |
always@(hit or addr0 or addr1 or addr2) |
begin |
address_out = addr0 ; |
if ( hit[1] ) |
address_out = addr1 ; |
else if ( hit[2] ) |
address_out = addr2 ; |
end |
|
`else |
`ifdef WB_IMAGE3 |
|
assign hit[5:4] = 2'b00 ; |
assign addr4 = 32'h0000_0000 ; |
assign addr5 = 32'h0000_0000 ; |
|
// address multiplexer |
always@(hit or addr0 or addr1 or addr2 or addr3) |
begin |
address_out = addr0 ; |
if ( hit[1] ) |
address_out = addr1 ; |
else if ( hit[2] ) |
address_out = addr2 ; |
else if ( hit[3] ) |
address_out = addr3 ; |
end |
|
|
`else |
`ifdef WB_IMAGE4 |
|
assign hit[5] = 1'b0 ; |
assign addr5 = 32'h0000_0000 ; |
|
// address multiplexer |
always@(hit or addr0 or addr1 or addr2 or addr3 or addr4) |
begin |
address_out = addr0 ; |
if ( hit[1] ) |
address_out = addr1 ; |
else if ( hit[2] ) |
address_out = addr2 ; |
else if ( hit[3] ) |
address_out = addr3 ; |
else if ( hit[4] ) |
address_out = addr4 ; |
end |
|
`else |
`ifdef WB_IMAGE5 |
// address multiplexer |
always@(hit or addr0 or addr1 or addr2 or addr3 or addr4 or addr5) |
begin |
address_out = addr0 ; |
if ( hit[1] ) |
address_out = addr1 ; |
else if ( hit[2] ) |
address_out = addr2 ; |
else if ( hit[3] ) |
address_out = addr3 ; |
else if ( hit[4] ) |
address_out = addr4 ; |
else if ( hit[5] ) |
address_out = addr5 ; |
end |
|
`else |
|
assign hit[5:2] = 4'b0000 ; |
assign addr2 = 32'h0000_0000 ; |
assign addr3 = 32'h0000_0000 ; |
assign addr4 = 32'h0000_0000 ; |
assign addr5 = 32'h0000_0000 ; |
|
// address multiplexer |
always@(hit or addr0 or addr1) |
begin |
address_out = addr0 ; |
if ( hit[1] ) |
address_out = addr1 ; |
end |
|
`endif |
`endif |
`endif |
`endif |
|
`ifdef WB_IMAGE3 |
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec2( |
.hit (hit[2]), |
.addr_out (addr2), |
.addr_in (address_in), |
.base_addr (bar2_in), |
.mask_addr (am2_in), |
.tran_addr (ta2_in), |
.at_en (at_en_in[2]) |
) ; |
|
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec3( |
.hit (hit[3]), |
.addr_out (addr3), |
.addr_in (address_in), |
.base_addr (bar3_in), |
.mask_addr (am3_in), |
.tran_addr (ta3_in), |
.at_en (at_en_in[3]) |
) ; |
`endif |
|
`ifdef WB_IMAGE4 |
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec2( |
.hit (hit[2]), |
.addr_out (addr2), |
.addr_in (address_in), |
.base_addr (bar2_in), |
.mask_addr (am2_in), |
.tran_addr (ta2_in), |
.at_en (at_en_in[2]) |
) ; |
|
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec3( |
.hit (hit[3]), |
.addr_out (addr3), |
.addr_in (address_in), |
.base_addr (bar3_in), |
.mask_addr (am3_in), |
.tran_addr (ta3_in), |
.at_en (at_en_in[3]) |
) ; |
|
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec4( |
.hit (hit[4]), |
.addr_out (addr4), |
.addr_in (address_in), |
.base_addr (bar4_in), |
.mask_addr (am4_in), |
.tran_addr (ta4_in), |
.at_en (at_en_in[4]) |
) ; |
`endif |
|
`ifdef WB_IMAGE5 |
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec2( |
.hit (hit[2]), |
.addr_out (addr2), |
.addr_in (address_in), |
.base_addr (bar2_in), |
.mask_addr (am2_in), |
.tran_addr (ta2_in), |
.at_en (at_en_in[2]) |
) ; |
|
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec3( |
.hit (hit[3]), |
.addr_out (addr3), |
.addr_in (address_in), |
.base_addr (bar3_in), |
.mask_addr (am3_in), |
.tran_addr (ta3_in), |
.at_en (at_en_in[3]) |
) ; |
|
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec4( |
.hit (hit[4]), |
.addr_out (addr4), |
.addr_in (address_in), |
.base_addr (bar4_in), |
.mask_addr (am4_in), |
.tran_addr (ta4_in), |
.at_en (at_en_in[4]) |
) ; |
|
DECODER #(`WB_NUM_OF_DEC_ADDR_LINES) dec5( |
.hit (hit[5]), |
.addr_out (addr5), |
.addr_in (address_in), |
.base_addr (bar5_in), |
.mask_addr (am5_in), |
.tran_addr (ta5_in), |
.at_en (at_en_in[5]) |
) ; |
`endif |
endmodule |
/verilog/serr_crit.v
0,0 → 1,72
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
`include "timescale.v" |
|
module 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_bridge32.v
0,0 → 1,1339
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "timescale.v" |
|
// 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 |
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, |
ACK_O, |
RTY_O, |
ERR_O, |
|
// WISHBONE master interface |
ADR_O, |
MDAT_I, |
MDAT_O, |
SEL_O, |
CYC_O, |
STB_O, |
WE_O, |
CAB_O, |
ACK_I, |
RTY_I, |
ERR_I, |
|
// pci interface - system pins |
PCI_CLK_IN, |
PCI_RSTn_IN, |
PCI_RSTn_OUT, |
PCI_INTAn_IN, |
PCI_INTAn_OUT, |
PCI_RSTn_EN_OUT, |
PCI_INTAn_EN_OUT, |
|
// arbitration pins |
PCI_REQn_OUT, |
PCI_REQn_EN_OUT, |
|
PCI_GNTn_IN, |
|
// protocol pins |
PCI_FRAMEn_IN, |
PCI_FRAMEn_OUT, |
PCI_FRAMEn_EN_OUT, |
PCI_IRDYn_EN_OUT, |
PCI_DEVSELn_EN_OUT, |
PCI_TRDYn_EN_OUT, |
PCI_STOPn_EN_OUT, |
PCI_AD_EN_OUT, |
PCI_CBEn_EN_OUT, |
|
PCI_IRDYn_IN, |
PCI_IRDYn_OUT, |
|
PCI_IDSEL_IN, |
|
PCI_DEVSELn_IN, |
PCI_DEVSELn_OUT, |
|
|
PCI_TRDYn_IN, |
PCI_TRDYn_OUT, |
|
PCI_STOPn_IN, |
PCI_STOPn_OUT, |
|
// data transfer pins |
PCI_AD_IN, |
PCI_AD_OUT, |
|
PCI_CBEn_IN, |
PCI_CBEn_OUT, |
|
// parity generation and checking pins |
PCI_PAR_IN, |
PCI_PAR_OUT, |
PCI_PAR_EN_OUT, |
|
PCI_PERRn_IN, |
PCI_PERRn_OUT, |
PCI_PERRn_EN_OUT, |
|
// system error pin |
PCI_SERRn_OUT, |
PCI_SERRn_EN_OUT |
); |
|
// 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 ; |
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 CAB_O ; |
input ACK_I ; |
input RTY_I ; |
input ERR_I ; |
|
// pci interface - system pins |
input PCI_CLK_IN ; |
input PCI_RSTn_IN ; |
output PCI_RSTn_OUT ; |
output PCI_RSTn_EN_OUT ; |
|
input PCI_INTAn_IN ; |
output PCI_INTAn_OUT ; |
output PCI_INTAn_EN_OUT ; |
|
// arbitration pins |
output PCI_REQn_OUT ; |
output PCI_REQn_EN_OUT ; |
|
input PCI_GNTn_IN ; |
|
// protocol pins |
input PCI_FRAMEn_IN ; |
output PCI_FRAMEn_OUT ; |
output PCI_FRAMEn_EN_OUT ; |
output PCI_IRDYn_EN_OUT ; |
output PCI_DEVSELn_EN_OUT ; |
output PCI_TRDYn_EN_OUT ; |
output PCI_STOPn_EN_OUT ; |
output [31:0] PCI_AD_EN_OUT ; |
output [3:0] PCI_CBEn_EN_OUT ; |
|
input PCI_IRDYn_IN ; |
output PCI_IRDYn_OUT ; |
|
input PCI_IDSEL_IN ; |
|
input PCI_DEVSELn_IN ; |
output PCI_DEVSELn_OUT ; |
|
input PCI_TRDYn_IN ; |
output PCI_TRDYn_OUT ; |
|
input PCI_STOPn_IN ; |
output PCI_STOPn_OUT ; |
|
// data transfer pins |
input [31:0] PCI_AD_IN ; |
output [31:0] PCI_AD_OUT ; |
|
input [3:0] PCI_CBEn_IN ; |
output [3:0] PCI_CBEn_OUT ; |
|
// parity generation and checking pins |
input PCI_PAR_IN ; |
output PCI_PAR_OUT ; |
output PCI_PAR_EN_OUT ; |
|
input PCI_PERRn_IN ; |
output PCI_PERRn_OUT ; |
output PCI_PERRn_EN_OUT ; |
|
// system error pin |
output PCI_SERRn_OUT ; |
output PCI_SERRn_EN_OUT ; |
|
// declare clock and reset wires |
wire pci_clk = PCI_CLK_IN ; |
wire wb_clk = CLK_I ; |
|
assign PCI_RSTn_OUT = 1'b0 ; |
|
`ifdef HOST |
// host implementation of the bridge gets its reset from WISHBONE bus - RST_I and propagates it to PCI bus |
wire reset = RST_I ; |
assign PCI_RSTn_EN_OUT = ~reset ; |
assign RST_O = 1'b0 ; |
`else |
`ifdef GUEST |
// guest implementation of the bridge gets its reset from PCI bus - RST# and propagates it to WISHBONE bus |
wire reset = ~PCI_RSTn_IN ; |
assign RST_O = reset ; |
assign PCI_RSTn_EN_OUT = 1'b1 ; |
`endif |
`endif |
|
/*================================================================================================================================================== |
Interrupts not yet implemented |
==================================================================================================================================================*/ |
assign INT_O = 1'b0 ; |
assign PCI_INTAn_EN_OUT = 1'b1 ; |
assign PCI_INTAn_OUT = 1'b1 ; |
|
/*================================================================================================================================================== |
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 |
==================================================================================================================================================*/ |
// 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_pciif_load_next_out ; |
wire wbu_pciif_frame_load_out ; |
|
// assign wishbone slave unit's outputs to top outputs where possible |
assign SDAT_O = wbu_sdata_out ; |
assign ACK_O = wbu_ack_out ; |
assign RTY_O = wbu_rty_out ; |
assign ERR_O = wbu_err_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 [3:0] pciu_sel_out ; |
wire pciu_cab_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_pciif_target_load_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 ADR_O = pciu_adr_out ; |
assign MDAT_O = pciu_mdata_out ; |
assign CYC_O = pciu_cyc_out ; |
assign STB_O = pciu_stb_out ; |
assign WE_O = pciu_we_out ; |
assign SEL_O = pciu_sel_out ; |
assign CAB_O = pciu_cab_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_out ; |
wire [7:0] conf_latency_tim_out ; |
wire [2:0] conf_int_pin_out ; |
|
wire [19:0] conf_pci_ba0_out ; |
wire [19:0] conf_pci_ba1_out ; |
wire [19:0] conf_pci_ba2_out ; |
wire [19:0] conf_pci_ba3_out ; |
wire [19:0] conf_pci_ba4_out ; |
wire [19:0] conf_pci_ba5_out ; |
wire [19:0] conf_pci_ta0_out ; |
wire [19:0] conf_pci_ta1_out ; |
wire [19:0] conf_pci_ta2_out ; |
wire [19:0] conf_pci_ta3_out ; |
wire [19:0] conf_pci_ta4_out ; |
wire [19:0] conf_pci_ta5_out ; |
wire [19:0] conf_pci_am0_out ; |
wire [19:0] conf_pci_am1_out ; |
wire [19:0] conf_pci_am2_out ; |
wire [19:0] conf_pci_am3_out ; |
wire [19:0] conf_pci_am4_out ; |
wire [19:0] 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 conf_pci_err_rty_exp_out ; |
wire conf_pci_error_en_out ; |
|
wire [19:0] conf_wb_ba0_out ; |
wire [19:0] conf_wb_ba1_out ; |
wire [19:0] conf_wb_ba2_out ; |
wire [19:0] conf_wb_ba3_out ; |
wire [19:0] conf_wb_ba4_out ; |
wire [19:0] 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:0] conf_wb_am0_out ; |
wire [19:0] conf_wb_am1_out ; |
wire [19:0] conf_wb_am2_out ; |
wire [19:0] conf_wb_am3_out ; |
wire [19:0] conf_wb_am4_out ; |
wire [19:0] conf_wb_am5_out ; |
wire [19:0] conf_wb_ta0_out ; |
wire [19:0] conf_wb_ta1_out ; |
wire [19:0] conf_wb_ta2_out ; |
wire [19:0] conf_wb_ta3_out ; |
wire [19:0] conf_wb_ta4_out ; |
wire [19:0] 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 conf_wb_err_rty_exp_out ; |
wire conf_wb_err_en_out ; |
wire [23:0] conf_ccyc_addr_out ; |
wire conf_soft_res_out ; |
wire conf_serr_int_en_out ; |
wire conf_perr_int_en_out ; |
wire conf_err_int_en_out ; |
wire conf_int_prop_en_out ; |
wire conf_pci_err_pending_out ; |
wire conf_wb_err_pending_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 [31:0] pci_mux_ad_en_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_EN_OUT = pci_mux_ad_en_out ; |
assign PCI_FRAMEn_EN_OUT = pci_mux_frame_en_out ; |
assign PCI_IRDYn_EN_OUT = pci_mux_irdy_en_out ; |
assign PCI_CBEn_EN_OUT = pci_mux_cbe_en_out ; |
|
assign PCI_PAR_OUT = pci_mux_par_out ; |
assign PCI_PAR_EN_OUT = pci_mux_par_en_out ; |
assign PCI_PERRn_OUT = pci_mux_perr_out ; |
assign PCI_PERRn_EN_OUT = pci_mux_perr_en_out ; |
assign PCI_SERRn_OUT = pci_mux_serr_out ; |
assign PCI_SERRn_EN_OUT = pci_mux_serr_en_out ; |
|
assign PCI_REQn_OUT = pci_mux_req_out ; |
assign PCI_REQn_EN_OUT = pci_mux_req_en_out ; |
|
assign PCI_TRDYn_EN_OUT = pci_mux_trdy_en_out ; |
assign PCI_DEVSELn_EN_OUT = pci_mux_devsel_en_out ; |
assign PCI_STOPn_EN_OUT = pci_mux_stop_en_out ; |
assign PCI_TRDYn_OUT = pci_mux_trdy_out ; |
assign PCI_DEVSELn_OUT = pci_mux_devsel_out ; |
assign PCI_STOPn_OUT = pci_mux_stop_out ; |
|
assign PCI_AD_OUT = pci_mux_ad_out ; |
assign PCI_FRAMEn_OUT = pci_mux_frame_out ; |
assign PCI_IRDYn_OUT = pci_mux_irdy_out ; |
assign PCI_CBEn_OUT = 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 ; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// WISHBONE SLAVE UNIT INPUTS |
wire [31:0] wbu_addr_in = ADR_I ; |
wire [31:0] wbu_sdata_in = SDAT_I ; |
wire wbu_cyc_in = CYC_I ; |
wire wbu_stb_in = STB_I ; |
wire wbu_we_in = WE_I ; |
wire [3:0] wbu_sel_in = SEL_I ; |
wire wbu_cab_in = CAB_I ; |
|
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[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar1_in = conf_wb_ba1_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar2_in = conf_wb_ba2_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar3_in = conf_wb_ba3_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar4_in = conf_wb_ba4_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar5_in = conf_wb_ba5_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am0_in = conf_wb_am0_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am1_in = conf_wb_am1_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am2_in = conf_wb_am2_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am3_in = conf_wb_am3_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am4_in = conf_wb_am4_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am5_in = conf_wb_am5_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta0_in = conf_wb_ta0_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta1_in = conf_wb_ta1_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta2_in = conf_wb_ta2_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta3_in = conf_wb_ta3_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta4_in = conf_wb_ta4_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta5_in = conf_wb_ta5_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
|
wire [23:0] wbu_ccyc_addr_in = conf_ccyc_addr_out ; |
wire wbu_master_enable_in = conf_pci_master_enable_out ; |
wire [7:0] wbu_cache_line_size_in = conf_cache_line_size_out ; |
|
wire wbu_pciif_gnt_in = PCI_GNTn_IN ; |
wire wbu_pciif_frame_in = in_reg_frame_out ; |
wire wbu_pciif_irdy_in = in_reg_irdy_out ; |
wire wbu_pciif_trdy_in = PCI_TRDYn_IN ; |
wire wbu_pciif_stop_in = PCI_STOPn_IN ; |
wire wbu_pciif_devsel_in = PCI_DEVSELn_IN ; |
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 wbu_err_pending_in = conf_wb_err_pending_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 ; |
|
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_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_err_pending_in (wbu_err_pending_in), |
.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_pciif_load_next_out (wbu_pciif_load_next_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) |
); |
|
// PCI TARGET UNIT INPUTS |
wire [31:0] pciu_mdata_in = MDAT_I ; |
wire pciu_ack_in = ACK_I ; |
wire pciu_rty_in = RTY_I ; |
wire pciu_err_in = 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_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 [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar0_in = conf_pci_ba0_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar1_in = conf_pci_ba1_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar2_in = conf_pci_ba2_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar3_in = conf_pci_ba3_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar4_in = conf_pci_ba4_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar5_in = conf_pci_ba5_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am0_in = conf_pci_am0_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am1_in = conf_pci_am1_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am2_in = conf_pci_am2_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am3_in = conf_pci_am3_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am4_in = conf_pci_am4_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am5_in = conf_pci_am5_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta0_in = conf_pci_ta0_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta1_in = conf_pci_ta1_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta2_in = conf_pci_ta2_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta3_in = conf_pci_ta3_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta4_in = conf_pci_ta4_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta5_in = conf_pci_ta5_out[19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] ; |
|
wire [7:0] pciu_cache_line_size_in = conf_cache_line_size_out ; |
|
wire pciu_pciif_frame_in = PCI_FRAMEn_IN ; |
wire pciu_pciif_irdy_in = PCI_IRDYn_IN ; |
wire pciu_pciif_idsel_in = PCI_IDSEL_IN ; |
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 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_err_pending_in = conf_pci_err_pending_out ; |
|
PCI_TARGET_UNIT pci_target_unit |
( |
.reset_in (reset), |
.wb_clock_in (wb_clk), |
.pci_clock_in (pci_clk), |
.ADR_O (pciu_adr_out), |
.MDATA_O (pciu_mdata_out), |
.MDATA_I (pciu_mdata_in), |
.CYC_O (pciu_cyc_out), |
.STB_O (pciu_stb_out), |
.WE_O (pciu_we_out), |
.SEL_O (pciu_sel_out), |
.ACK_I (pciu_ack_in), |
.RTY_I (pciu_rty_in), |
.ERR_I (pciu_err_in), |
.CAB_O (pciu_cab_out), |
.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_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_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_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_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_pciif_target_load_out (pciu_pciif_target_load_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_err_pending_in (pciu_err_pending_in), |
.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) |
); |
|
|
// 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_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 ; |
|
///////////////////////////////////////////////////////////////////////////////////////////////// |
// Interrupts not implemented yet |
wire conf_isr_int_prop_in = 1'b0 ; |
wire conf_isr_err_int_in = 1'b0 ; |
wire conf_par_err_int_in = 1'b0 ; |
wire conf_sys_err_int_in = 1'b0 ; |
///////////////////////////////////////////////////////////////////////////////////////////////// |
|
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 (conf_cache_line_size_out), |
.latency_tim (conf_latency_tim_out), |
.int_pin (conf_int_pin_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_sig (conf_pci_err_sig_in), |
.pci_error_addr (conf_pci_err_addr_in), |
.pci_error_data (conf_pci_err_data_in), |
.pci_error_rty_exp_set (conf_pci_err_rty_exp_out), |
.pci_error_en (conf_pci_error_en_out), |
.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), |
.wb_error_rty_exp_set (conf_wb_err_rty_exp_out), |
.wb_error_en (conf_wb_err_en_out), |
.config_addr (conf_ccyc_addr_out), |
.icr_soft_res (conf_soft_res_out), |
.serr_int_en (conf_serr_int_en_out), |
.perr_int_en (conf_perr_int_en_out), |
.error_int_en (conf_err_int_en_out), |
.int_prop_en (conf_int_prop_en_out), |
.isr_int_prop (conf_isr_int_prop_in), |
.isr_err_int (conf_isr_err_int_in), |
.isr_par_err_int (conf_par_err_int_in), |
.isr_sys_err_int (conf_sys_err_int_in), |
.pci_error_sig_set (conf_pci_err_pending_out), |
.wb_error_sig_set (conf_wb_err_pending_out) |
) ; |
|
// 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_pciif_target_load_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_pciif_load_next_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 ; |
|
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), |
.target_load_in (pci_mux_tar_load_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), |
|
.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) |
); |
|
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), |
.master_load_in (pci_mux_mas_load_in), |
.target_load_in (pci_mux_tar_load_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), |
|
.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_IN ; |
wire parchk_pci_perr_in = PCI_PERRn_IN ; |
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_CBEn_IN ; |
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_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_GNTn_IN ; |
wire in_reg_frame_in = PCI_FRAMEn_IN ; |
wire in_reg_irdy_in = PCI_IRDYn_IN ; |
wire in_reg_trdy_in = PCI_TRDYn_IN ; |
wire in_reg_stop_in = PCI_STOPn_IN ; |
wire in_reg_devsel_in = PCI_DEVSELn_IN ; |
wire in_reg_idsel_in = PCI_IDSEL_IN ; |
wire [31:0] in_reg_ad_in = PCI_AD_IN ; |
wire [3:0] in_reg_cbe_in = PCI_CBEn_IN ; |
|
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/wbr_fifo_control.v
0,0 → 1,322
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 "constants.v" |
`include "timescale.v" |
`ifdef FPGA |
// fifo design in FPGA will be synchronous |
`ifdef SYNCHRONOUS |
`else |
`define SYNCHRONOUS |
`endif |
`endif |
|
module 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 registers |
// grey code pipeline for write address |
reg [(ADDR_LENGTH - 1):0] wgrey_addr ; // current |
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_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] ; |
|
// FF for registered empty flag |
reg 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 ; |
|
`ifdef SYNCHRONOUS |
|
reg wclock_nempty_detect ; |
always@(posedge reset_in or posedge wclock_in) |
begin |
if (reset_in) |
wclock_nempty_detect <= #`FF_DELAY 1'b0 ; |
else |
wclock_nempty_detect <= #`FF_DELAY (rgrey_addr != wgrey_addr) ; |
end |
|
// special synchronizing mechanism for different implementations - in synchronous imp., empty is prolonged for 1 clock edge if no write clock comes after initial write |
reg stretched_empty ; |
always@(posedge rclock_in or posedge clear) |
begin |
if(clear) |
stretched_empty <= #`FF_DELAY 1'b1 ; |
else |
stretched_empty <= #`FF_DELAY empty && ~wclock_nempty_detect ; |
end |
|
// empty output is actual empty + 1 read clock cycle ( stretched empty ) |
assign empty_out = empty || stretched_empty ; |
|
//rallow generation |
assign rallow = renable_in && ~empty && ~stretched_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 ; |
|
// enable for this register |
wire raddr_plus_one_en = rallow ; |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
raddr_plus_one[(ADDR_LENGTH - 1):1] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0}} ; |
raddr_plus_one[0] <= #`FF_DELAY 1'b1 ; |
end |
else if (raddr_plus_one_en) |
raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ; |
end |
|
// raddr is filled with raddr_plus_one on rising read clock edge when rallow is high |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
// initial value is 000......00 |
raddr <= #`FF_DELAY { ADDR_LENGTH{1'b0}} ; |
else if (rallow) |
raddr <= #`FF_DELAY raddr_plus_one ; |
end |
|
`else |
// asynchronous RAM storage for FIFOs - somewhat simpler control logic |
//rallow generation |
assign rallow = renable_in && ~empty ; |
|
assign rallow_out = rallow ; |
|
// read address counter - normal counter, nothing to it |
// for asynchronous implementation, there is no need for pointing to next address. |
// On clock edge that read is performed, read address will change and on the next clock edge |
// asynchronous memory will provide next data |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
// initial value is 000......00 |
raddr <= #`FF_DELAY { ADDR_LENGTH{1'b0}} ; |
else if (rallow) |
raddr <= #`FF_DELAY raddr + 1'b1 ; |
end |
|
assign empty_out = empty ; |
assign raddr_out = raddr ; |
`endif |
|
/*----------------------------------------------------------------------------------------------- |
Read address control consists of Read address counter and Grey Address pipeline |
There are 3 Grey addresses: |
- rgrey_addr is Grey Code of current read address |
- rgrey_next is Grey Code of next read address |
--------------------------------------------------------------------------------------------------*/ |
|
// grey code register for read address - represents current Read Address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100.......01 |
rgrey_addr[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_addr[(ADDR_LENGTH - 2):1] <= #`FF_DELAY { (ADDR_LENGTH - 2){1'b0} } ; |
rgrey_addr[0] <= #`FF_DELAY 1'b1 ; |
end |
else |
if (rallow) |
rgrey_addr <= #`FF_DELAY rgrey_next ; |
end |
|
// grey code register for next read address - represents Grey Code of next read address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......00 |
rgrey_next[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_next[(ADDR_LENGTH - 2):0] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0} } ; |
end |
else |
if (rallow) |
rgrey_next <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ; |
end |
|
/*-------------------------------------------------------------------------------------------- |
Write address control consists of write address counter and two Grey Code Registers: |
- wgrey_addr represents current Grey Coded write address |
- wgrey_next represents Grey Coded next write address |
----------------------------------------------------------------------------------------------*/ |
// grey code register for write address |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100.....001 |
wgrey_addr[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
wgrey_addr[(ADDR_LENGTH - 2):1] <= #`FF_DELAY { (ADDR_LENGTH - 2){1'b0} } ; |
wgrey_addr[0] <= #`FF_DELAY 1'b1 ; |
end |
else |
if (wallow) |
wgrey_addr <= #`FF_DELAY wgrey_next ; |
end |
|
// grey code register for next write address |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......00 |
wgrey_next[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
wgrey_next[(ADDR_LENGTH - 2):0] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0} } ; |
end |
else |
if (wallow) |
wgrey_next <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ; |
end |
|
// write address counter - nothing special |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
// initial value 00.........00 |
waddr <= #`FF_DELAY { (ADDR_LENGTH){1'b0} } ; |
else |
if (wallow) |
waddr <= #`FF_DELAY waddr + 1'b1 ; |
end |
|
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Registered empty control: |
registered empty is set on rising edge of rclock_in, |
when only one location is used and read in/from fifo. It's kept high until something is written to FIFO, which is registered on |
the next read clock. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
// combinatorial input for registered emty FlipFlop |
wire reg_empty = (rallow && (rgrey_next == wgrey_addr)) || (rgrey_addr == wgrey_addr) ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
empty <= #`FF_DELAY 1'b1 ; |
else |
empty <= #`FF_DELAY reg_empty ; |
end |
|
endmodule |
/verilog/pci_target32_ad_en_crit.v
0,0 → 1,74
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_target32_ad_en_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.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 |
|
`include "constants.v" |
`include "timescale.v" |
|
module PCI_TARGET32_AD_EN_CRIT |
( |
ad_en_w, |
ad_en_w_frm, |
pci_frame_in, |
pci_ad_en_out |
); |
|
input ad_en_w ; // AD enable signal (composed without critical signals) that do not need critical FRAME input |
input ad_en_w_frm ; // AD enable signal (composed without critical signals) that needs AND with critical FRAME input |
input pci_frame_in ; // critical constrained input signal |
|
output pci_ad_en_out ; // AD enable output |
|
// AD enable output with preserved hierarchy for minimum delay! |
assign pci_ad_en_out = (ad_en_w || (ad_en_w_frm && ~pci_frame_in)) ; |
|
|
endmodule |
/verilog/dp_async_ram.v
0,0 → 1,82
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "dp_async_ram.v" //// |
//// //// |
//// This file is part of the "PCI bridge" project //// |
//// http://www.opencores.org/cores/pci/ //// |
//// //// |
//// Author(s): //// |
//// - mihad@opencores.org //// |
//// - Miha Dolenc //// |
//// //// |
//// All additional information is avaliable in the README.pdf //// |
//// 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.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// Revision 1.1 2001/08/06 18:12:43 mihad |
// Pocasi delamo kompletno zadevo |
// |
// |
|
// behavioral dual port asynchronous read / synchronous write RAM |
`include "constants.v" |
`include "timescale.v" |
|
module DP_ASYNC_RAM(reset_in, wclock_in, data_in, raddr_in, waddr_in, data_out, wenable_in); |
|
parameter ADDR_LENGTH = 7 ; |
parameter SIZE = 128 ; |
input reset_in ; |
input wclock_in ; |
input [39:0] data_in ; |
input [(ADDR_LENGTH - 1):0] raddr_in ; |
input [(ADDR_LENGTH - 1):0] waddr_in ; |
output [39:0] data_out ; |
input wenable_in ; |
|
reg [39:0] mem [(SIZE - 1):0] ; |
wire [(ADDR_LENGTH - 1):0] raddr = raddr_in ; |
wire [(ADDR_LENGTH - 1):0] waddr = waddr_in ; |
|
assign data_out = mem[raddr] ; |
|
always@(posedge wclock_in) |
begin |
if (wenable_in) |
mem[waddr] <= #`FF_DELAY data_in ; |
end |
|
endmodule |
/verilog/conf_space.v
0,0 → 1,2871
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "timescale.v" |
|
/*----------------------------------------------------------------------------------------------------------- |
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 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, latency_tim, int_pin, |
// 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_sig, pci_error_addr, pci_error_data, |
// output from pci error control and status register |
pci_error_en, pci_error_sig_set, pci_error_rty_exp_set, |
// 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 wb error control and status register |
wb_error_en, wb_error_sig_set, wb_error_rty_exp_set, |
// output from conf. cycle generation register (sddress) & int. control register |
config_addr, icr_soft_res, serr_int_en, perr_int_en, error_int_en, int_prop_en, |
// input to interrupt status register |
isr_int_prop, isr_err_int, isr_par_err_int, isr_sys_err_int ) ; |
|
|
/*########################################################################################################### |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
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 ; |
reg [31 : 0] r_conf_data_out ; |
// input data |
input [31 : 0] w_conf_data_in ; |
// 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 ; |
output [7 : 0] latency_tim ; |
output [2 : 0] int_pin ; // only 3 LSbits are important! |
// PCI output from image registers |
output [31 : 12] pci_base_addr0 ; |
output [31 : 12] pci_base_addr1 ; |
output [31 : 12] pci_base_addr2 ; |
output [31 : 12] pci_base_addr3 ; |
output [31 : 12] pci_base_addr4 ; |
output [31 : 12] 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 : 12] pci_addr_mask0 ; |
output [31 : 12] pci_addr_mask1 ; |
output [31 : 12] pci_addr_mask2 ; |
output [31 : 12] pci_addr_mask3 ; |
output [31 : 12] pci_addr_mask4 ; |
output [31 : 12] pci_addr_mask5 ; |
output [31 : 12] pci_tran_addr0 ; |
output [31 : 12] pci_tran_addr1 ; |
output [31 : 12] pci_tran_addr2 ; |
output [31 : 12] pci_tran_addr3 ; |
output [31 : 12] pci_tran_addr4 ; |
output [31 : 12] 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_sig ; |
input [31 : 0] pci_error_addr ; |
input [31 : 0] pci_error_data ; |
// PCI output from pci error control and status register |
output pci_error_en ; |
output pci_error_sig_set ; |
output pci_error_rty_exp_set ; |
// WISHBONE output from image registers |
output [31 : 12] wb_base_addr0 ; |
output [31 : 12] wb_base_addr1 ; |
output [31 : 12] wb_base_addr2 ; |
output [31 : 12] wb_base_addr3 ; |
output [31 : 12] wb_base_addr4 ; |
output [31 : 12] 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 : 12] wb_addr_mask0 ; |
output [31 : 12] wb_addr_mask1 ; |
output [31 : 12] wb_addr_mask2 ; |
output [31 : 12] wb_addr_mask3 ; |
output [31 : 12] wb_addr_mask4 ; |
output [31 : 12] wb_addr_mask5 ; |
output [31 : 12] wb_tran_addr0 ; |
output [31 : 12] wb_tran_addr1 ; |
output [31 : 12] wb_tran_addr2 ; |
output [31 : 12] wb_tran_addr3 ; |
output [31 : 12] wb_tran_addr4 ; |
output [31 : 12] 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 ; |
// WISHBONE output from wb error control and status register |
output wb_error_en ; |
output wb_error_sig_set ; |
output wb_error_rty_exp_set ; |
// GENERAL output from conf. cycle generation register & int. control register |
output [23 : 0] config_addr ; |
output icr_soft_res ; |
output serr_int_en ; |
output perr_int_en ; |
output error_int_en ; |
output int_prop_en ; |
// GENERAL input to interrupt status register |
input isr_int_prop ; |
input isr_err_int ; |
input isr_par_err_int ; |
input isr_sys_err_int ; |
|
|
/*########################################################################################################### |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
REGISTERS definition |
==================== |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
###########################################################################################################*/ |
|
|
/*########################################################################################################### |
------------------------------------------------------------------------------------------------------------- |
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_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! |
-----------------------------------------------------------------------------------------------------------*/ |
parameter def_pci_image0_addr_map = `PCI_AM0 ; //20'hfff0_0 |
parameter def_pci_image1_addr_map = `PCI_AM1 ; //20'hfff0_0 |
parameter def_pci_image2_addr_map = `PCI_AM2 ; //20'h0000_0 |
parameter def_pci_image3_addr_map = `PCI_AM3 ; //20'h0000_0 |
parameter def_pci_image4_addr_map = `PCI_AM4 ; //20'h0000_0 |
parameter def_pci_image5_addr_map = `PCI_AM5 ; //20'h0000_0 |
|
/*----------------------------------------------------------------------------------------------------------- |
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 !!! |
parameter def_wb_image1_addr_map = 20'h0000_0 ; |
parameter def_wb_image2_addr_map = 20'h0000_0 ; |
parameter def_wb_image3_addr_map = 20'h0000_0 ; |
parameter def_wb_image4_addr_map = 20'h0000_0 ; |
parameter 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_IMAGE6 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_IMAGE6 (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. |
-----------------------------------------------------------------------------------------------------------*/ |
parameter pci_image0 = 1 ; |
reg [31 : 12] pci_ba0_bit31_12 ; |
`ifdef HOST |
`ifdef PCI_IMAGE6 // if PCI bridge is HOST and IMAGE0 is assigned as general image space |
parameter pci_image0_conf = 1 ; |
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 assigned to PCI configuration space |
parameter pci_image0_conf = 0 ; |
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 = `PCI_AM0 ; // 4KBytes of configuration space is minimum |
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 |
parameter pci_image0_conf = 0 ; |
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 = `PCI_AM0 ; // 4KBytes of configuration space is minimum |
wire [31 : 12] pci_ta0 = 20'h0000_0 ; // NO address translation needed |
`endif |
parameter pci_image1 = 1 ; |
reg [2 : 1] pci_img_ctrl1_bit2_1 ; |
reg [31 : 12] pci_ba1_bit31_12 ; |
reg pci_ba1_bit0 ; |
reg [31 : 12] pci_am1 ; |
reg [31 : 12] pci_ta1 ; |
|
// IMAGE0 and IMAGE1 are included by default, meanwhile other IMAGEs are optional !!! |
`ifdef PCI_IMAGE1 |
parameter pci_image2 = 0 ; |
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 ; |
|
parameter pci_image3 = 0 ; |
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 ; |
|
parameter pci_image4 = 0 ; |
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 ; |
|
parameter pci_image5 = 0 ; |
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 |
`ifdef PCI_IMAGE2 |
parameter pci_image2 = 1 ; |
reg [2 : 1] pci_img_ctrl2_bit2_1 ; |
reg [31 : 12] pci_ba2_bit31_12 ; |
reg pci_ba2_bit0 ; |
reg [31 : 12] pci_am2 ; |
reg [31 : 12] pci_ta2 ; |
|
parameter pci_image3 = 0 ; |
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 ; |
|
parameter pci_image4 = 0 ; |
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 ; |
|
parameter pci_image5 = 0 ; |
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 |
`ifdef PCI_IMAGE3 |
parameter pci_image2 = 1 ; |
reg [2 : 1] pci_img_ctrl2_bit2_1 ; |
reg [31 : 12] pci_ba2_bit31_12 ; |
reg pci_ba2_bit0 ; |
reg [31 : 12] pci_am2 ; |
reg [31 : 12] pci_ta2 ; |
|
parameter pci_image3 = 1 ; |
reg [2 : 1] pci_img_ctrl3_bit2_1 ; |
reg [31 : 12] pci_ba3_bit31_12 ; |
reg pci_ba3_bit0 ; |
reg [31 : 12] pci_am3 ; |
reg [31 : 12] pci_ta3 ; |
|
parameter pci_image4 = 0 ; |
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 ; |
|
parameter pci_image5 = 0 ; |
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 |
`ifdef PCI_IMAGE4 |
parameter pci_image2 = 1 ; |
reg [2 : 1] pci_img_ctrl2_bit2_1 ; |
reg [31 : 12] pci_ba2_bit31_12 ; |
reg pci_ba2_bit0 ; |
reg [31 : 12] pci_am2 ; |
reg [31 : 12] pci_ta2 ; |
|
parameter pci_image3 = 1 ; |
reg [2 : 1] pci_img_ctrl3_bit2_1 ; |
reg [31 : 12] pci_ba3_bit31_12 ; |
reg pci_ba3_bit0 ; |
reg [31 : 12] pci_am3 ; |
reg [31 : 12] pci_ta3 ; |
|
parameter pci_image4 = 1 ; |
reg [2 : 1] pci_img_ctrl4_bit2_1 ; |
reg [31 : 12] pci_ba4_bit31_12 ; |
reg pci_ba4_bit0 ; |
reg [31 : 12] pci_am4 ; |
reg [31 : 12] pci_ta4 ; |
|
parameter pci_image5 = 0 ; |
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 |
`ifdef PCI_IMAGE5 |
parameter pci_image2 = 1 ; |
reg [2 : 1] pci_img_ctrl2_bit2_1 ; |
reg [31 : 12] pci_ba2_bit31_12 ; |
reg pci_ba2_bit0 ; |
reg [31 : 12] pci_am2 ; |
reg [31 : 12] pci_ta2 ; |
|
parameter pci_image3 = 1 ; |
reg [2 : 1] pci_img_ctrl3_bit2_1 ; |
reg [31 : 12] pci_ba3_bit31_12 ; |
reg pci_ba3_bit0 ; |
reg [31 : 12] pci_am3 ; |
reg [31 : 12] pci_ta3 ; |
|
parameter pci_image4 = 1 ; |
reg [2 : 1] pci_img_ctrl4_bit2_1 ; |
reg [31 : 12] pci_ba4_bit31_12 ; |
reg pci_ba4_bit0 ; |
reg [31 : 12] pci_am4 ; |
reg [31 : 12] pci_ta4 ; |
|
parameter pci_image5 = 1 ; |
reg [2 : 1] pci_img_ctrl5_bit2_1 ; |
reg [31 : 12] pci_ba5_bit31_12 ; |
reg pci_ba5_bit0 ; |
reg [31 : 12] pci_am5 ; |
reg [31 : 12] pci_ta5 ; |
`endif |
`ifdef PCI_IMAGE6 |
parameter pci_image2 = 1 ; |
reg [2 : 1] pci_img_ctrl2_bit2_1 ; |
reg [31 : 12] pci_ba2_bit31_12 ; |
reg pci_ba2_bit0 ; |
reg [31 : 12] pci_am2 ; |
reg [31 : 12] pci_ta2 ; |
|
parameter pci_image3 = 1 ; |
reg [2 : 1] pci_img_ctrl3_bit2_1 ; |
reg [31 : 12] pci_ba3_bit31_12 ; |
reg pci_ba3_bit0 ; |
reg [31 : 12] pci_am3 ; |
reg [31 : 12] pci_ta3 ; |
|
parameter pci_image4 = 1 ; |
reg [2 : 1] pci_img_ctrl4_bit2_1 ; |
reg [31 : 12] pci_ba4_bit31_12 ; |
reg pci_ba4_bit0 ; |
reg [31 : 12] pci_am4 ; |
reg [31 : 12] pci_ta4 ; |
|
parameter pci_image5 = 1 ; |
reg [2 : 1] pci_img_ctrl5_bit2_1 ; |
reg [31 : 12] pci_ba5_bit31_12 ; |
reg pci_ba5_bit0 ; |
reg [31 : 12] pci_am5 ; |
reg [31 : 12] pci_ta5 ; |
`endif |
reg [31 : 24] pci_err_cs_bit31_24 ; |
reg pci_err_cs_bit10 ; |
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 |
parameter wb_image0 = 1 ; |
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_IMAGE0 and WB_IMAGE1 are included by default meanwhile others are optional ! |
parameter wb_image1 = 1 ; |
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_IMAGE1 |
parameter wb_image2 = 0 ; |
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 ; |
|
parameter wb_image3 = 0 ; |
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 ; |
|
parameter wb_image4 = 0 ; |
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 ; |
|
parameter wb_image5 = 0 ; |
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 |
`ifdef WB_IMAGE2 |
parameter wb_image2 = 1 ; |
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 ; |
|
parameter wb_image3 = 0 ; |
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 ; |
|
parameter wb_image4 = 0 ; |
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 ; |
|
parameter wb_image5 = 0 ; |
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 |
`ifdef WB_IMAGE3 |
parameter wb_image2 = 1 ; |
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 ; |
|
parameter wb_image3 = 1 ; |
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 ; |
|
parameter wb_image4 = 0 ; |
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 ; |
|
parameter wb_image5 = 0 ; |
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 |
`ifdef WB_IMAGE4 |
parameter wb_image2 = 1 ; |
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 ; |
|
parameter wb_image3 = 1 ; |
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 ; |
|
parameter wb_image4 = 1 ; |
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 ; |
|
parameter wb_image5 = 0 ; |
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 |
`ifdef WB_IMAGE5 |
parameter wb_image2 = 1 ; |
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 ; |
|
parameter wb_image3 = 1 ; |
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 ; |
|
parameter wb_image4 = 1 ; |
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 ; |
|
parameter wb_image5 = 1 ; |
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 ; |
`endif |
reg [31 : 24] wb_err_cs_bit31_24 ; |
reg [10 : 8] wb_err_cs_bit10_8 ; |
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. |
-----------------------------------------------------------------------------------------------------------*/ |
reg [23 : 2] cnf_addr_bit23_2 ; |
reg cnf_addr_bit0 ; |
// 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. |
4 LSbits in the Interrupt Status register are indicating System Error Int, Parity Error Int, Error |
Int and Inerrupt respecively. |
-----------------------------------------------------------------------------------------------------------*/ |
reg icr_bit31 ; |
reg [3 : 0] icr_bit3_0 ; |
reg [3 : 0] isr_bit3_0 ; |
|
|
/*########################################################################################################### |
------------------------------------------------------------------------------------------------------------- |
|
|
-----------------------------------------------------------------------------------------------------------*/ |
|
always@(r_re or |
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_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_8 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_bit3_0 or isr_bit3_0 |
) |
begin |
if (r_re == 1'b1) |
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, 2'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: r_conf_data_out = { pci_ba0_bit31_12, 11'h000, pci_ba0_bit0 } & { pci_am0[31:12], 12'h001 } ; |
4'h5: r_conf_data_out = { pci_ba1_bit31_12, 11'h000, pci_ba1_bit0 } & { pci_am1[31:12], 12'h001 } ; |
4'h6: r_conf_data_out = { pci_ba2_bit31_12, 11'h000, pci_ba2_bit0 } & { pci_am2[31:12], 12'h001 } ; |
4'h7: r_conf_data_out = { pci_ba3_bit31_12, 11'h000, pci_ba3_bit0 } & { pci_am3[31:12], 12'h001 } ; |
4'h8: r_conf_data_out = { pci_ba4_bit31_12, 11'h000, pci_ba4_bit0 } & { pci_am4[31:12], 12'h001 } ; |
4'h9: r_conf_data_out = { pci_ba5_bit31_12, 11'h000, pci_ba5_bit0 } & { pci_am5[31:12], 12'h001 } ; |
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 : r_conf_data_out = { pci_ba0_bit31_12, 11'h000, pci_ba0_bit0 } & { pci_am0[31:12], 12'h001 } ; |
`P_AM0_ADDR : r_conf_data_out = { pci_am0, 12'h000 } ; |
`P_TA0_ADDR : r_conf_data_out = { pci_ta0, 12'h000 } ; |
`P_IMG_CTRL1_ADDR: r_conf_data_out = { 29'h00000000, pci_img_ctrl1_bit2_1, 1'h0 } ; |
`P_BA1_ADDR : r_conf_data_out = { pci_ba1_bit31_12, 11'h000, pci_ba1_bit0 } & { pci_am1[31:12], 12'h001 } ; |
`P_AM1_ADDR : r_conf_data_out = { pci_am1, 12'h000 } ; |
`P_TA1_ADDR : r_conf_data_out = { pci_ta1, 12'h000 } ; |
`P_IMG_CTRL2_ADDR: r_conf_data_out = { 29'h00000000, pci_img_ctrl2_bit2_1, 1'h0 } ; |
`P_BA2_ADDR : r_conf_data_out = { pci_ba2_bit31_12, 11'h000, pci_ba2_bit0 } & { pci_am2[31:12], 12'h001 } ; |
`P_AM2_ADDR : r_conf_data_out = { pci_am2, 12'h000 } ; |
`P_TA2_ADDR : r_conf_data_out = { pci_ta2, 12'h000 } ; |
`P_IMG_CTRL3_ADDR: r_conf_data_out = { 29'h00000000, pci_img_ctrl3_bit2_1, 1'h0 } ; |
`P_BA3_ADDR : r_conf_data_out = { pci_ba3_bit31_12, 11'h000, pci_ba3_bit0 } & { pci_am3[31:12], 12'h001 } ; |
`P_AM3_ADDR : r_conf_data_out = { pci_am3, 12'h000 } ; |
`P_TA3_ADDR : r_conf_data_out = { pci_ta3, 12'h000 } ; |
`P_IMG_CTRL4_ADDR: r_conf_data_out = { 29'h00000000, pci_img_ctrl4_bit2_1, 1'h0 } ; |
`P_BA4_ADDR : r_conf_data_out = { pci_ba4_bit31_12, 11'h000, pci_ba4_bit0 } & { pci_am4[31:12], 12'h001 } ; |
`P_AM4_ADDR : r_conf_data_out = { pci_am4, 12'h000 } ; |
`P_TA4_ADDR : r_conf_data_out = { pci_ta4, 12'h000 } ; |
`P_IMG_CTRL5_ADDR: r_conf_data_out = { 29'h00000000, pci_img_ctrl5_bit2_1, 1'h0 } ; |
`P_BA5_ADDR : r_conf_data_out = { pci_ba5_bit31_12, 11'h000, pci_ba5_bit0 } & { pci_am5[31:12], 12'h001 } ; |
`P_AM5_ADDR : r_conf_data_out = { pci_am5, 12'h000 } ; |
`P_TA5_ADDR : r_conf_data_out = { pci_ta5, 12'h000 } ; |
`P_ERR_CS_ADDR : r_conf_data_out = { pci_err_cs_bit31_24, 13'h0000, pci_err_cs_bit10, 1'h0, |
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 : r_conf_data_out = { wb_ba1_bit31_12, 11'h000, wb_ba1_bit0 } & { wb_am1[31:12], 12'h001 } ; |
`W_AM1_ADDR : r_conf_data_out = { wb_am1, 12'h000 } ; |
`W_TA1_ADDR : r_conf_data_out = { wb_ta1, 12'h000 } ; |
`W_IMG_CTRL2_ADDR: r_conf_data_out = { 29'h00000000, wb_img_ctrl2_bit2_0 } ; |
`W_BA2_ADDR : r_conf_data_out = { wb_ba2_bit31_12, 11'h000, wb_ba2_bit0 } & { wb_am2[31:12], 12'h001 } ; |
`W_AM2_ADDR : r_conf_data_out = { wb_am2, 12'h000 } ; |
`W_TA2_ADDR : r_conf_data_out = { wb_ta2, 12'h000 } ; |
`W_IMG_CTRL3_ADDR: r_conf_data_out = { 29'h00000000, wb_img_ctrl3_bit2_0 } ; |
`W_BA3_ADDR : r_conf_data_out = { wb_ba3_bit31_12, 11'h000, wb_ba3_bit0 } & { wb_am3[31:12], 12'h001 } ; |
`W_AM3_ADDR : r_conf_data_out = { wb_am3, 12'h000 } ; |
`W_TA3_ADDR : r_conf_data_out = { wb_ta3, 12'h000 } ; |
`W_IMG_CTRL4_ADDR: r_conf_data_out = { 29'h00000000, wb_img_ctrl4_bit2_0 } ; |
`W_BA4_ADDR : r_conf_data_out = { wb_ba4_bit31_12, 11'h000, wb_ba4_bit0 } & { wb_am4[31:12], 12'h001 } ; |
`W_AM4_ADDR : r_conf_data_out = { wb_am4, 12'h000 } ; |
`W_TA4_ADDR : r_conf_data_out = { wb_ta4, 12'h000 } ; |
`W_IMG_CTRL5_ADDR: r_conf_data_out = { 29'h00000000, wb_img_ctrl5_bit2_0 } ; |
`W_BA5_ADDR : r_conf_data_out = { wb_ba5_bit31_12, 11'h000, wb_ba5_bit0 } & { wb_am5[31:12], 12'h001 } ; |
`W_AM5_ADDR : r_conf_data_out = { wb_am5, 12'h000 } ; |
`W_TA5_ADDR : r_conf_data_out = { wb_ta5, 12'h000 } ; |
`W_ERR_CS_ADDR : r_conf_data_out = { wb_err_cs_bit31_24, 13'h0000, wb_err_cs_bit10_8, |
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, 27'h0000_000, icr_bit3_0 } ; |
`ISR_ADDR : r_conf_data_out = { 28'h0000_000, isr_bit3_0 } ; |
|
default : r_conf_data_out = 32'h0000_0000 ; |
endcase |
end |
endcase |
end |
else |
r_conf_data_out = 32'h0000_0000 ; |
end |
|
always@(w_re or |
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_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_8 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_bit3_0 or isr_bit3_0 |
) |
begin |
if (w_re == 1'b1) |
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: w_conf_data_out = { r_device_id, r_vendor_id } ; |
4'h1: w_conf_data_out = { status_bit15_11, r_status_bit10_9, status_bit8, 2'h0, r_status_bit5, |
5'h00, 7'h00, command_bit8, 1'h0, command_bit6, 3'h0, command_bit2_0 } ; |
4'h2: w_conf_data_out = { r_class_code, r_revision_id } ; |
4'h3: w_conf_data_out = { 8'h00, r_header_type, latency_timer, cache_line_size_reg } ; |
4'h4: w_conf_data_out = { pci_ba0_bit31_12, 11'h000, pci_ba0_bit0 } & { pci_am0[31:12], 12'h001 } ; |
4'h5: w_conf_data_out = { pci_ba1_bit31_12, 11'h000, pci_ba1_bit0 } & { pci_am1[31:12], 12'h001 } ; |
4'h6: w_conf_data_out = { pci_ba2_bit31_12, 11'h000, pci_ba2_bit0 } & { pci_am2[31:12], 12'h001 } ; |
4'h7: w_conf_data_out = { pci_ba3_bit31_12, 11'h000, pci_ba3_bit0 } & { pci_am3[31:12], 12'h001 } ; |
4'h8: w_conf_data_out = { pci_ba4_bit31_12, 11'h000, pci_ba4_bit0 } & { pci_am4[31:12], 12'h001 } ; |
4'h9: w_conf_data_out = { pci_ba5_bit31_12, 11'h000, pci_ba5_bit0 } & { pci_am5[31:12], 12'h001 } ; |
4'hf: w_conf_data_out = { r_max_lat, r_min_gnt, r_interrupt_pin, interrupt_line } ; |
default : w_conf_data_out = 32'h0000_0000 ; |
endcase |
end |
default : |
w_conf_data_out = 32'h0000_0000 ; |
endcase |
end |
default : |
begin |
// PCI target - configuration space |
case (w_conf_address_in[7:2]) |
`P_IMG_CTRL0_ADDR: w_conf_data_out = { 29'h00000000, pci_img_ctrl0_bit2_1, 1'h0 } ; |
`P_BA0_ADDR : w_conf_data_out = { pci_ba0_bit31_12, 11'h000, pci_ba0_bit0 } & { pci_am0[31:12], 12'h001 } ; |
`P_AM0_ADDR : w_conf_data_out = { pci_am0, 12'h000 } ; |
`P_TA0_ADDR : w_conf_data_out = { pci_ta0, 12'h000 } ; |
`P_IMG_CTRL1_ADDR: w_conf_data_out = { 29'h00000000, pci_img_ctrl1_bit2_1, 1'h0 } ; |
`P_BA1_ADDR : w_conf_data_out = { pci_ba1_bit31_12, 11'h000, pci_ba1_bit0 } & { pci_am1[31:12], 12'h001 } ; |
`P_AM1_ADDR : w_conf_data_out = { pci_am1, 12'h000 } ; |
`P_TA1_ADDR : w_conf_data_out = { pci_ta1, 12'h000 } ; |
`P_IMG_CTRL2_ADDR: w_conf_data_out = { 29'h00000000, pci_img_ctrl2_bit2_1, 1'h0 } ; |
`P_BA2_ADDR : w_conf_data_out = { pci_ba2_bit31_12, 11'h000, pci_ba2_bit0 } & { pci_am2[31:12], 12'h001 } ; |
`P_AM2_ADDR : w_conf_data_out = { pci_am2, 12'h000 } ; |
`P_TA2_ADDR : w_conf_data_out = { pci_ta2, 12'h000 } ; |
`P_IMG_CTRL3_ADDR: w_conf_data_out = { 29'h00000000, pci_img_ctrl3_bit2_1, 1'h0 } ; |
`P_BA3_ADDR : w_conf_data_out = { pci_ba3_bit31_12, 11'h000, pci_ba3_bit0 } & { pci_am3[31:12], 12'h001 } ; |
`P_AM3_ADDR : w_conf_data_out = { pci_am3, 12'h000 } ; |
`P_TA3_ADDR : w_conf_data_out = { pci_ta3, 12'h000 } ; |
`P_IMG_CTRL4_ADDR: w_conf_data_out = { 29'h00000000, pci_img_ctrl4_bit2_1, 1'h0 } ; |
`P_BA4_ADDR : w_conf_data_out = { pci_ba4_bit31_12, 11'h000, pci_ba4_bit0 } & { pci_am4[31:12], 12'h001 } ; |
`P_AM4_ADDR : w_conf_data_out = { pci_am4, 12'h000 } ; |
`P_TA4_ADDR : w_conf_data_out = { pci_ta4, 12'h000 } ; |
`P_IMG_CTRL5_ADDR: w_conf_data_out = { 29'h00000000, pci_img_ctrl5_bit2_1, 1'h0 } ; |
`P_BA5_ADDR : w_conf_data_out = { pci_ba5_bit31_12, 11'h000, pci_ba5_bit0 } & { pci_am5[31:12], 12'h001 } ; |
`P_AM5_ADDR : w_conf_data_out = { pci_am5, 12'h000 } ; |
`P_TA5_ADDR : w_conf_data_out = { pci_ta5, 12'h000 } ; |
`P_ERR_CS_ADDR : w_conf_data_out = { pci_err_cs_bit31_24, 13'h0000, pci_err_cs_bit10, 1'h0, |
pci_err_cs_bit8, 7'h00, pci_err_cs_bit0 } ; |
`P_ERR_ADDR_ADDR : w_conf_data_out = pci_err_addr ; |
`P_ERR_DATA_ADDR : w_conf_data_out = pci_err_data ; |
// WB slave - configuration space |
`WB_CONF_SPC_BAR_ADDR: w_conf_data_out = { wb_ba0_bit31_12, 11'h000, wb_ba0_bit0 } ; |
`W_IMG_CTRL1_ADDR: w_conf_data_out = { 29'h00000000, wb_img_ctrl1_bit2_0 } ; |
`W_BA1_ADDR : w_conf_data_out = { wb_ba1_bit31_12, 11'h000, wb_ba1_bit0 } & { wb_am1[31:12], 12'h001 } ; |
`W_AM1_ADDR : w_conf_data_out = { wb_am1, 12'h000 } ; |
`W_TA1_ADDR : w_conf_data_out = { wb_ta1, 12'h000 } ; |
`W_IMG_CTRL2_ADDR: w_conf_data_out = { 29'h00000000, wb_img_ctrl2_bit2_0 } ; |
`W_BA2_ADDR : w_conf_data_out = { wb_ba2_bit31_12, 11'h000, wb_ba2_bit0 } & { wb_am2[31:12], 12'h001 } ; |
`W_AM2_ADDR : w_conf_data_out = { wb_am2, 12'h000 } ; |
`W_TA2_ADDR : w_conf_data_out = { wb_ta2, 12'h000 } ; |
`W_IMG_CTRL3_ADDR: w_conf_data_out = { 29'h00000000, wb_img_ctrl3_bit2_0 } ; |
`W_BA3_ADDR : w_conf_data_out = { wb_ba3_bit31_12, 11'h000, wb_ba3_bit0 } & { wb_am3[31:12], 12'h001 } ; |
`W_AM3_ADDR : w_conf_data_out = { wb_am3, 12'h000 } ; |
`W_TA3_ADDR : w_conf_data_out = { wb_ta3, 12'h000 } ; |
`W_IMG_CTRL4_ADDR: w_conf_data_out = { 29'h00000000, wb_img_ctrl4_bit2_0 } ; |
`W_BA4_ADDR : w_conf_data_out = { wb_ba4_bit31_12, 11'h000, wb_ba4_bit0 } & { wb_am4[31:12], 12'h001 } ; |
`W_AM4_ADDR : w_conf_data_out = { wb_am4, 12'h000 } ; |
`W_TA4_ADDR : w_conf_data_out = { wb_ta4, 12'h000 } ; |
`W_IMG_CTRL5_ADDR: w_conf_data_out = { 29'h00000000, wb_img_ctrl5_bit2_0 } ; |
`W_BA5_ADDR : w_conf_data_out = { wb_ba5_bit31_12, 11'h000, wb_ba5_bit0 } & { wb_am5[31:12], 12'h001 } ; |
`W_AM5_ADDR : w_conf_data_out = { wb_am5, 12'h000 } ; |
`W_TA5_ADDR : w_conf_data_out = { wb_ta5, 12'h000 } ; |
`W_ERR_CS_ADDR : w_conf_data_out = { wb_err_cs_bit31_24, 13'h0000, wb_err_cs_bit10_8, |
7'h00, wb_err_cs_bit0 } ; |
`W_ERR_ADDR_ADDR : w_conf_data_out = wb_err_addr ; |
`W_ERR_DATA_ADDR : w_conf_data_out = wb_err_data ; |
|
`CNF_ADDR_ADDR : w_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 : w_conf_data_out = { icr_bit31, 27'h0000_000, icr_bit3_0 } ; |
`ISR_ADDR : w_conf_data_out = { 28'h0000_000, isr_bit3_0 } ; |
default : w_conf_data_out = 32'h0000_0000 ; |
endcase |
end |
endcase |
end |
else |
w_conf_data_out = 32'h0000_0000 ; |
end |
|
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 PCI_IMAGE6 // if PCI bridge is HOST and IMAGE0 is assigned as general image space |
pci_img_ctrl0_bit2_1 <= 2'h0 ; |
// pci_ba0_bit31_12 is always a register (never parameter) !!! |
pci_ba0_bit0 <= 1'h0 ; |
pci_am0 <= def_pci_image0_addr_map ; |
pci_ta0 <= 20'h0000_0 ; |
`endif |
`endif |
pci_ba0_bit31_12 <= 20'h0000_0 ; |
|
pci_img_ctrl1_bit2_1 <= 2'h0 ; |
pci_ba1_bit31_12 <= 20'h0000_0 ; pci_ba1_bit0 <= 1'h0 ; |
pci_am1 <= def_pci_image1_addr_map ; |
pci_ta1 <= 20'h0000_0 ; |
`ifdef PCI_IMAGE2 |
pci_img_ctrl2_bit2_1 <= 2'h0 ; |
pci_ba2_bit31_12 <= 20'h0000_0 ; pci_ba2_bit0 <= 1'h0 ; |
pci_am2 <= def_pci_image2_addr_map ; |
pci_ta2 <= 20'h0000_0 ; |
`endif |
`ifdef PCI_IMAGE3 |
pci_img_ctrl2_bit2_1 <= 2'h0 ; |
pci_ba2_bit31_12 <= 20'h0000_0 ; pci_ba2_bit0 <= 1'h0 ; |
pci_am2 <= def_pci_image2_addr_map ; |
pci_ta2 <= 20'h0000_0 ; |
pci_img_ctrl3_bit2_1 <= 2'h0 ; |
pci_ba3_bit31_12 <= 20'h0000_0 ; pci_ba3_bit0 <= 1'h0 ; |
pci_am3 <= def_pci_image3_addr_map ; |
pci_ta3 <= 20'h0000_0 ; |
`endif |
`ifdef PCI_IMAGE4 |
pci_img_ctrl2_bit2_1 <= 2'h0 ; |
pci_ba2_bit31_12 <= 20'h0000_0 ; pci_ba2_bit0 <= 1'h0 ; |
pci_am2 <= def_pci_image2_addr_map ; |
pci_ta2 <= 20'h0000_0 ; |
pci_img_ctrl3_bit2_1 <= 2'h0 ; |
pci_ba3_bit31_12 <= 20'h0000_0 ; pci_ba3_bit0 <= 1'h0 ; |
pci_am3 <= def_pci_image3_addr_map ; |
pci_ta3 <= 20'h0000_0 ; |
pci_img_ctrl4_bit2_1 <= 2'h0 ; |
pci_ba4_bit31_12 <= 20'h0000_0 ; pci_ba4_bit0 <= 1'h0 ; |
pci_am4 <= def_pci_image4_addr_map ; |
pci_ta4 <= 20'h0000_0 ; |
`endif |
`ifdef PCI_IMAGE5 |
pci_img_ctrl2_bit2_1 <= 2'h0 ; |
pci_ba2_bit31_12 <= 20'h0000_0 ; pci_ba2_bit0 <= 1'h0 ; |
pci_am2 <= def_pci_image2_addr_map ; |
pci_ta2 <= 20'h0000_0 ; |
pci_img_ctrl3_bit2_1 <= 2'h0 ; |
pci_ba3_bit31_12 <= 20'h0000_0 ; pci_ba3_bit0 <= 1'h0 ; |
pci_am3 <= def_pci_image3_addr_map ; |
pci_ta3 <= 20'h0000_0 ; |
pci_img_ctrl4_bit2_1 <= 2'h0 ; |
pci_ba4_bit31_12 <= 20'h0000_0 ; pci_ba4_bit0 <= 1'h0 ; |
pci_am4 <= def_pci_image4_addr_map ; |
pci_ta4 <= 20'h0000_0 ; |
pci_img_ctrl5_bit2_1 <= 2'h0 ; |
pci_ba5_bit31_12 <= 20'h0000_0 ; pci_ba5_bit0 <= 1'h0 ; |
pci_am5 <= def_pci_image5_addr_map ; |
pci_ta5 <= 20'h0000_0 ; |
`endif |
`ifdef PCI_IMAGE6 |
pci_img_ctrl2_bit2_1 <= 2'h0 ; |
pci_ba2_bit31_12 <= 20'h0000_0 ; pci_ba2_bit0 <= 1'h0 ; |
pci_am2 <= def_pci_image2_addr_map ; |
pci_ta2 <= 20'h0000_0 ; |
pci_img_ctrl3_bit2_1 <= 2'h0 ; |
pci_ba3_bit31_12 <= 20'h0000_0 ; pci_ba3_bit0 <= 1'h0 ; |
pci_am3 <= def_pci_image3_addr_map ; |
pci_ta3 <= 20'h0000_0 ; |
pci_img_ctrl4_bit2_1 <= 2'h0 ; |
pci_ba4_bit31_12 <= 20'h0000_0 ; pci_ba4_bit0 <= 1'h0 ; |
pci_am4 <= def_pci_image4_addr_map ; |
pci_ta4 <= 20'h0000_0 ; |
pci_img_ctrl5_bit2_1 <= 2'h0 ; |
pci_ba5_bit31_12 <= 20'h0000_0 ; pci_ba5_bit0 <= 1'h0 ; |
pci_am5 <= def_pci_image5_addr_map ; |
pci_ta5 <= 20'h0000_0 ; |
`endif |
/*pci_err_cs_bit31_24 ; pci_err_cs_bit10 ; 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 <= def_wb_image1_addr_map ; |
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 <= def_wb_image2_addr_map ; |
wb_ta2 <= 20'h0000_0 ; |
`endif |
`ifdef WB_IMAGE3 |
wb_img_ctrl2_bit2_0 <= 3'h0 ; |
wb_ba2_bit31_12 <= 20'h0000_0 ; wb_ba2_bit0 <= 1'h0 ; |
wb_am2 <= def_wb_image2_addr_map ; |
wb_ta2 <= 20'h0000_0 ; |
wb_img_ctrl3_bit2_0 <= 3'h0 ; |
wb_ba3_bit31_12 <= 20'h0000_0 ; wb_ba3_bit0 <= 1'h0 ; |
wb_am3 <= def_wb_image3_addr_map ; |
wb_ta3 <= 20'h0000_0 ; |
`endif |
`ifdef WB_IMAGE4 |
wb_img_ctrl2_bit2_0 <= 3'h0 ; |
wb_ba2_bit31_12 <= 20'h0000_0 ; wb_ba2_bit0 <= 1'h0 ; |
wb_am2 <= def_wb_image2_addr_map ; |
wb_ta2 <= 20'h0000_0 ; |
wb_img_ctrl3_bit2_0 <= 3'h0 ; |
wb_ba3_bit31_12 <= 20'h0000_0 ; wb_ba3_bit0 <= 1'h0 ; |
wb_am3 <= def_wb_image3_addr_map ; |
wb_ta3 <= 20'h0000_0 ; |
wb_img_ctrl4_bit2_0 <= 3'h0 ; |
wb_ba4_bit31_12 <= 20'h0000_0 ; wb_ba4_bit0 <= 1'h0 ; |
wb_am4 <= def_wb_image4_addr_map ; |
wb_ta4 <= 20'h0000_0 ; |
`endif |
`ifdef WB_IMAGE5 |
wb_img_ctrl2_bit2_0 <= 3'h0 ; |
wb_ba2_bit31_12 <= 20'h0000_0 ; wb_ba2_bit0 <= 1'h0 ; |
wb_am2 <= def_wb_image2_addr_map ; |
wb_ta2 <= 20'h0000_0 ; |
wb_img_ctrl3_bit2_0 <= 3'h0 ; |
wb_ba3_bit31_12 <= 20'h0000_0 ; wb_ba3_bit0 <= 1'h0 ; |
wb_am3 <= def_wb_image3_addr_map ; |
wb_ta3 <= 20'h0000_0 ; |
wb_img_ctrl4_bit2_0 <= 3'h0 ; |
wb_ba4_bit31_12 <= 20'h0000_0 ; wb_ba4_bit0 <= 1'h0 ; |
wb_am4 <= def_wb_image4_addr_map ; |
wb_ta4 <= 20'h0000_0 ; |
wb_img_ctrl5_bit2_0 <= 3'h0 ; |
wb_ba5_bit31_12 <= 20'h0000_0 ; wb_ba5_bit0 <= 1'h0 ; |
wb_am5 <= def_wb_image5_addr_map ; |
wb_ta5 <= 20'h0000_0 ; |
`endif |
/*wb_err_cs_bit31_24 ; wb_err_cs_bit10_8 ;*/ wb_err_cs_bit0 <= 1'h0 ; |
/*wb_err_addr ;*/ |
/*wb_err_data ;*/ |
|
cnf_addr_bit23_2 <= 22'h0000_00 ; cnf_addr_bit0 <= 1'h0 ; |
icr_bit31 <= 1'h0 ; icr_bit3_0 <= 4'h0 ; |
/*isr_bit3_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_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_8[10] <= 1'b1 ; |
wb_err_cs_bit10_8[9] <= 1'b1 ; |
wb_err_cs_bit10_8[8] <= 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_bit3_0[3] <= 1'b1 & icr_bit3_0[3] ; |
isr_bit3_0[2] <= 1'b1 & icr_bit3_0[2] ; |
isr_bit3_0[1] <= 1'b1 & icr_bit3_0[1] ; |
isr_bit3_0[0] <= 1'b1 & icr_bit3_0[0] ; |
-----------------------------------------------------------------------------------------------------------*/ |
// Here follows normal writting to registers (only to their valid bits) ! |
else |
begin |
if (w_we == 1'b1) |
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'h1: |
begin |
if (w_byte_en[1] == 1'b0) |
command_bit8 <= #`FF_DELAY w_conf_data_in[8] ; |
if (w_byte_en[0] == 1'b0) |
begin |
command_bit6 <= #`FF_DELAY w_conf_data_in[6] ; |
command_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
end |
4'h3: |
begin |
if (w_byte_en[1] == 1'b0) |
latency_timer <= #`FF_DELAY w_conf_data_in[15:8] ; |
if (w_byte_en[0] == 1'b0) |
cache_line_size_reg <= #`FF_DELAY w_conf_data_in[7:0] ; |
end |
4'h4: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba0_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba0_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba0_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
4'h5: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba1_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba1_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba1_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba1_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`ifdef PCI_IMAGE2 |
4'h6: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`endif |
`ifdef PCI_IMAGE3 |
4'h6: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
4'h7: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba3_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba3_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba3_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba3_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`endif |
`ifdef PCI_IMAGE4 |
4'h6: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
4'h7: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba3_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba3_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba3_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba3_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
4'h8: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba4_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba4_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba4_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba4_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`endif |
`ifdef PCI_IMAGE5 |
4'h6: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
4'h7: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba3_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba3_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba3_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba3_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
4'h8: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba4_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba4_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba4_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba4_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
4'h9: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba5_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba5_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba5_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba5_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`endif |
`ifdef PCI_IMAGE6 |
4'h6: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
4'h7: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba3_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba3_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba3_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba3_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
4'h8: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba4_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba4_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba4_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba4_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
4'h9: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba5_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba5_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba5_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba5_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`endif |
4'hf: |
begin |
if (w_byte_en[0] == 1'b0) |
interrupt_line <= #`FF_DELAY w_conf_data_in[7:0] ; |
end |
default : |
begin |
end |
endcase |
end |
default : |
begin |
end |
endcase |
end |
default : |
begin |
// PCI target - configuration space |
case (w_conf_address_in[7:2]) |
`ifdef HOST |
`ifdef PCI_IMAGE6 // if PCI bridge is HOST and IMAGE0 is assigned as general image space |
`P_IMG_CTRL0_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl0_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`endif |
`endif |
// pci_ba0_bit31_12 & pci_ba0_bit0 are always registers (never parameters) !!! |
`P_BA0_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba0_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba0_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba0_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
`ifdef HOST |
`ifdef PCI_IMAGE6 // if PCI bridge is HOST and IMAGE0 is assigned as general image space |
if (w_byte_en[0] == 1'b0) |
pci_ba0_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
`endif |
`endif |
end |
`ifdef HOST |
`ifdef PCI_IMAGE6 // if PCI bridge is HOST and IMAGE0 is assigned as general image space |
`P_AM0_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am0[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am0[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am0[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA0_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta0[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta0[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta0[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`endif |
`endif |
`P_IMG_CTRL1_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl1_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA1_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba1_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba1_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba1_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba1_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM1_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am1[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am1[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am1[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA1_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta1[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta1[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta1[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`ifdef PCI_IMAGE2 |
`P_IMG_CTRL2_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl2_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`endif |
`ifdef PCI_IMAGE3 |
`P_IMG_CTRL2_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl2_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_IMG_CTRL3_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl3_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba3_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba3_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba3_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba3_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`endif |
`ifdef PCI_IMAGE4 |
`P_IMG_CTRL2_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl2_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_IMG_CTRL3_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl3_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba3_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba3_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba3_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba3_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_IMG_CTRL4_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl4_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba4_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba4_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba4_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba4_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am4[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am4[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am4[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta4[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta4[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta4[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`endif |
`ifdef PCI_IMAGE5 |
`P_IMG_CTRL2_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl2_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_IMG_CTRL3_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl3_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba3_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba3_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba3_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba3_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_IMG_CTRL4_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl4_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba4_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba4_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba4_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba4_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am4[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am4[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am4[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta4[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta4[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta4[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_IMG_CTRL5_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl5_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA5_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba5_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba5_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba5_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba5_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM5_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am5[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am5[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am5[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA5_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta5[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta5[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta5[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`endif |
`ifdef PCI_IMAGE6 |
`P_IMG_CTRL2_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl2_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_IMG_CTRL3_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl3_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba3_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba3_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba3_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba3_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_IMG_CTRL4_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl4_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba4_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba4_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba4_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba4_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am4[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am4[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am4[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta4[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta4[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta4[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_IMG_CTRL5_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_img_ctrl5_bit2_1 <= #`FF_DELAY w_conf_data_in[2:1] ; |
end |
`P_BA5_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ba5_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ba5_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ba5_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
pci_ba5_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`P_AM5_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_am5[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_am5[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_am5[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`P_TA5_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
pci_ta5[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
pci_ta5[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
pci_ta5[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`endif |
`P_ERR_CS_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
pci_err_cs_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
// WB slave - configuration space |
`W_IMG_CTRL1_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_img_ctrl1_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
`W_BA1_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ba1_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ba1_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ba1_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
wb_ba1_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`W_AM1_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_am1[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_am1[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_am1[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_TA1_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ta1[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ta1[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ta1[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`ifdef WB_IMAGE2 |
`W_IMG_CTRL2_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_img_ctrl2_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
`W_BA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
wb_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`W_AM2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_am2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_am2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_am2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_TA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ta2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ta2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ta2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`endif |
`ifdef WB_IMAGE3 |
`W_IMG_CTRL2_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_img_ctrl2_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
`W_BA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
wb_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`W_AM2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_am2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_am2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_am2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_TA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ta2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ta2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ta2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_IMG_CTRL3_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_img_ctrl3_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
`W_BA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ba3_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ba3_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ba3_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
wb_ba3_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`W_AM3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_am3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_am3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_am3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_TA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ta3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ta3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ta3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`endif |
`ifdef WB_IMAGE4 |
`W_IMG_CTRL2_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_img_ctrl2_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
`W_BA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
wb_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`W_AM2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_am2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_am2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_am2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_TA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ta2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ta2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ta2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_IMG_CTRL3_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_img_ctrl3_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
`W_BA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ba3_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ba3_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ba3_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
wb_ba3_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`W_AM3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_am3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_am3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_am3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_TA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ta3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ta3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ta3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_IMG_CTRL4_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_img_ctrl4_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
`W_BA4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ba4_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ba4_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ba4_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
wb_ba4_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`W_AM4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_am4[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_am4[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_am4[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_TA4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ta4[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ta4[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ta4[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`endif |
`ifdef WB_IMAGE5 |
`W_IMG_CTRL2_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_img_ctrl2_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
`W_BA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ba2_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ba2_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ba2_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
wb_ba2_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`W_AM2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_am2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_am2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_am2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_TA2_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ta2[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ta2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ta2[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_IMG_CTRL3_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_img_ctrl3_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
`W_BA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ba3_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ba3_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ba3_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
wb_ba3_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`W_AM3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_am3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_am3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_am3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_TA3_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ta3[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ta3[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ta3[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_IMG_CTRL4_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_img_ctrl4_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
`W_BA4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ba4_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ba4_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ba4_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
wb_ba4_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`W_AM4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_am4[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_am4[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_am4[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_TA4_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ta4[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ta4[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ta4[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_IMG_CTRL5_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_img_ctrl5_bit2_0 <= #`FF_DELAY w_conf_data_in[2:0] ; |
end |
`W_BA5_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ba5_bit31_12[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ba5_bit31_12[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ba5_bit31_12[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
if (w_byte_en[0] == 1'b0) |
wb_ba5_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
`W_AM5_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_am5[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_am5[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_am5[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`W_TA5_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
wb_ta5[31:24] <= #`FF_DELAY w_conf_data_in[31:24] ; |
if (w_byte_en[2] == 1'b0) |
wb_ta5[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
wb_ta5[15:12] <= #`FF_DELAY w_conf_data_in[15:12] ; |
end |
`endif |
`W_ERR_CS_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
wb_err_cs_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
|
`CNF_ADDR_ADDR: |
begin |
if (w_byte_en[2] == 1'b0) |
cnf_addr_bit23_2[23:16] <= #`FF_DELAY w_conf_data_in[23:16] ; |
if (w_byte_en[1] == 1'b0) |
cnf_addr_bit23_2[15:8] <= #`FF_DELAY w_conf_data_in[15:8] ; |
if (w_byte_en[0] == 1'b0) |
begin |
cnf_addr_bit23_2[7:2] <= #`FF_DELAY w_conf_data_in[7:2] ; |
cnf_addr_bit0 <= #`FF_DELAY w_conf_data_in[0] ; |
end |
end |
// `CNF_DATA_ADDR: implemented elsewhere !!! |
// `INT_ACK_ADDR : implemented elsewhere !!! |
`ICR_ADDR: |
begin |
if (w_byte_en[3] == 1'b0) |
icr_bit31 <= #`FF_DELAY w_conf_data_in[31] ; |
if (w_byte_en[0] == 1'b0) |
icr_bit3_0 <= #`FF_DELAY w_conf_data_in[3:0] ; |
end |
default : |
begin |
end |
endcase |
end |
endcase |
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_bit10 ; |
reg delete_pci_err_cs_bit8 ; |
reg delete_wb_err_cs_bit10 ; |
reg delete_wb_err_cs_bit8 ; |
reg delete_isr_bit3 ; |
reg delete_isr_bit2 ; |
reg delete_isr_bit1 ; |
reg delete_isr_bit0 ; |
|
// If nothing is written into, then the value is '0' (W_WE = 0) !!! |
wire delete_status_bit15_in = w_we ? w_conf_data_in[31] : 1'b0 ; |
wire delete_status_bit14_in = w_we ? w_conf_data_in[30] : 1'b0 ; |
wire delete_status_bit13_in = w_we ? w_conf_data_in[29] : 1'b0 ; |
wire delete_status_bit12_in = w_we ? w_conf_data_in[28] : 1'b0 ; |
wire delete_status_bit11_in = w_we ? w_conf_data_in[27] : 1'b0 ; |
wire delete_status_bit8_in = w_we ? w_conf_data_in[24] : 1'b0 ; |
wire delete_pci_err_cs_bit10_in = w_we ? w_conf_data_in[10] : 1'b0 ; |
wire delete_pci_err_cs_bit8_in = w_we ? w_conf_data_in[8] : 1'b0 ; |
wire delete_wb_err_cs_bit10_in = w_we ? w_conf_data_in[10] : 1'b0 ; |
wire delete_wb_err_cs_bit8_in = w_we ? w_conf_data_in[8] : 1'b0 ; |
wire delete_isr_bit3_in = w_we ? w_conf_data_in[3] : 1'b0 ; |
wire delete_isr_bit2_in = w_we ? w_conf_data_in[2] : 1'b0 ; |
wire delete_isr_bit1_in = w_we ? w_conf_data_in[1] : 1'b0 ; |
wire delete_isr_bit0_in = w_we ? w_conf_data_in[0] : 1'b0 ; |
|
// This are aditional register bits, which are resets when their value is '1' !!! |
always@(posedge w_clock or posedge reset) |
begin |
if (reset) // Asynchronous RESET sets signals to '1' |
begin |
delete_status_bit15 <= #`FF_DELAY 1'b1 ; |
delete_status_bit14 <= #`FF_DELAY 1'b1 ; |
delete_status_bit13 <= #`FF_DELAY 1'b1 ; |
delete_status_bit12 <= #`FF_DELAY 1'b1 ; |
delete_status_bit11 <= #`FF_DELAY 1'b1 ; |
delete_status_bit8 <= #`FF_DELAY 1'b1 ; |
delete_pci_err_cs_bit10 <= #`FF_DELAY 1'b1 ; |
delete_pci_err_cs_bit8 <= #`FF_DELAY 1'b1 ; |
delete_wb_err_cs_bit10 <= #`FF_DELAY 1'b1 ; |
delete_wb_err_cs_bit8 <= #`FF_DELAY 1'b1 ; |
delete_isr_bit3 <= #`FF_DELAY 1'b1 ; |
delete_isr_bit2 <= #`FF_DELAY 1'b1 ; |
delete_isr_bit1 <= #`FF_DELAY 1'b1 ; |
delete_isr_bit0 <= #`FF_DELAY 1'b1 ; |
end |
else |
begin // If '1' is written into, then it also sets signals to '1' |
case (w_conf_address_in[8]) |
1'b0 : |
// if (~w_conf_address_in[8]) |
begin |
case ({w_conf_address_in[7], w_conf_address_in[6]}) |
2'b00 : |
// if ((~w_conf_address_in[7]) && (~w_conf_address_in[6])) |
begin |
// PCI header - configuration space |
case (w_conf_address_in[5:2]) |
4'h1: |
begin |
if (w_byte_en[3] == 1'b0) |
begin |
delete_status_bit15 <= #`FF_DELAY delete_status_bit15_in ; |
delete_status_bit14 <= #`FF_DELAY delete_status_bit14_in ; |
delete_status_bit13 <= #`FF_DELAY delete_status_bit13_in ; |
delete_status_bit12 <= #`FF_DELAY delete_status_bit12_in ; |
delete_status_bit11 <= #`FF_DELAY delete_status_bit11_in ; |
delete_status_bit8 <= #`FF_DELAY delete_status_bit8_in ; |
end |
end |
default : |
begin |
end |
endcase |
end |
default : |
begin |
end |
endcase |
end |
default : |
// else |
begin |
// PCI target - configuration space |
case (w_conf_address_in[7:2]) |
`P_ERR_CS_ADDR: |
begin |
if (w_byte_en[1] == 1'b0) |
begin |
delete_pci_err_cs_bit10 <= #`FF_DELAY delete_pci_err_cs_bit10_in ; |
delete_pci_err_cs_bit8 <= #`FF_DELAY delete_pci_err_cs_bit8_in ; |
end |
end |
`W_ERR_CS_ADDR: |
begin |
if (w_byte_en[1] == 1'b0) |
begin |
delete_wb_err_cs_bit10 <= #`FF_DELAY delete_wb_err_cs_bit10_in ; |
delete_wb_err_cs_bit8 <= #`FF_DELAY delete_wb_err_cs_bit8_in ; |
end |
end |
`ISR_ADDR: |
begin |
if (w_byte_en[0] == 1'b0) |
begin |
delete_isr_bit3 <= #`FF_DELAY delete_isr_bit3_in ; |
delete_isr_bit2 <= #`FF_DELAY delete_isr_bit2_in ; |
delete_isr_bit1 <= #`FF_DELAY delete_isr_bit1_in ; |
delete_isr_bit0 <= #`FF_DELAY delete_isr_bit0_in ; |
end |
end |
default : |
begin |
end |
endcase |
end |
endcase |
end |
end |
|
// Following are REGISTERS , which have "asynchronous & synchronous RESET" and synchronous SET on pci_clk ! |
always@(posedge pci_clk or posedge delete_status_bit15) |
begin |
if (delete_status_bit15) // Asynchronous reset |
status_bit15_11[15] <= #`FF_DELAY 1'b0 ; |
else |
if (perr_in) |
status_bit15_11[15] <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge pci_clk or posedge delete_status_bit14) |
begin |
if (delete_status_bit14) // Asynchronous reset |
status_bit15_11[14] <= #`FF_DELAY 1'b0 ; |
else |
if (serr_in) |
status_bit15_11[14] <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge pci_clk or posedge delete_status_bit13) |
begin |
if (delete_status_bit13) // Asynchronous reset |
status_bit15_11[13] <= #`FF_DELAY 1'b0 ; |
else |
if (master_abort_recv) |
status_bit15_11[13] <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge pci_clk or posedge delete_status_bit12) |
begin |
if (delete_status_bit12) // Asynchronous reset |
status_bit15_11[12] <= #`FF_DELAY 1'b0 ; |
else |
if (target_abort_recv) |
status_bit15_11[12] <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge pci_clk or posedge delete_status_bit11) |
begin |
if (delete_status_bit11) // Asynchronous reset |
status_bit15_11[11] <= #`FF_DELAY 1'b0 ; |
else |
if (target_abort_set) |
status_bit15_11[11] <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge pci_clk or posedge delete_status_bit8) |
begin |
if (delete_status_bit8) // Asynchronous reset |
status_bit8 <= #`FF_DELAY 1'b0 ; |
else |
if (master_data_par_err && command_bit6) |
status_bit8 <= #`FF_DELAY 1'b1 ; |
end |
|
// Following are REGISTERS , which have "asynchronous & synchronous RESET" and synchronous SET on w_clock ! |
always@(posedge wb_clk or posedge delete_pci_err_cs_bit10) |
begin |
if (delete_pci_err_cs_bit10) // Asynchronous reset |
pci_err_cs_bit10 <= #`FF_DELAY 1'b0 ; |
else |
if (pci_error_rty_exp && pci_err_cs_bit0) |
pci_err_cs_bit10 <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge wb_clk or posedge delete_pci_err_cs_bit8) |
begin |
if (delete_pci_err_cs_bit8) // Asynchronous reset |
pci_err_cs_bit8 <= #`FF_DELAY 1'b0 ; |
else |
if (pci_error_sig && pci_err_cs_bit0) |
pci_err_cs_bit8 <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge wb_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
begin |
pci_err_cs_bit31_24 <= #`FF_DELAY 8'h00 ; |
pci_err_addr <= #`FF_DELAY 32'h0000_0000 ; |
pci_err_data <= #`FF_DELAY 32'h0000_0000 ; |
end |
else |
if (pci_error_sig && pci_err_cs_bit0) |
begin |
pci_err_cs_bit31_24 <= #`FF_DELAY { pci_error_be, pci_error_bc } ; |
pci_err_addr <= #`FF_DELAY pci_error_addr ; |
pci_err_data <= #`FF_DELAY pci_error_data ; |
end |
end |
|
always@(posedge pci_clk or posedge delete_wb_err_cs_bit10) |
begin |
if (delete_wb_err_cs_bit10) // Asynchronous reset |
wb_err_cs_bit10_8[10] <= #`FF_DELAY 1'b0 ; |
else |
if (wb_error_rty_exp && wb_err_cs_bit0) |
wb_err_cs_bit10_8[10] <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
wb_err_cs_bit10_8[9] <= #`FF_DELAY 1'b0 ; |
else |
if (wb_error_sig && wb_err_cs_bit0) |
wb_err_cs_bit10_8[9] <= #`FF_DELAY wb_error_es ; |
end |
always@(posedge pci_clk or posedge delete_wb_err_cs_bit8) |
begin |
if (delete_wb_err_cs_bit8) // Asynchronous reset |
wb_err_cs_bit10_8[8] <= #`FF_DELAY 1'b0 ; |
else |
if (wb_error_sig && wb_err_cs_bit0) |
wb_err_cs_bit10_8[8] <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge pci_clk or posedge reset) |
begin |
if (reset) // Asynchronous reset |
begin |
wb_err_cs_bit31_24 <= #`FF_DELAY 8'h00 ; |
wb_err_addr <= #`FF_DELAY 32'h0000_0000 ; |
wb_err_data <= #`FF_DELAY 32'h0000_0000 ; |
end |
else |
if (wb_error_sig && wb_err_cs_bit0) |
begin |
wb_err_cs_bit31_24 <= #`FF_DELAY { wb_error_be, wb_error_bc } ; |
wb_err_addr <= #`FF_DELAY wb_error_addr ; |
wb_err_data <= #`FF_DELAY wb_error_data ; |
end |
end |
|
always@(posedge w_clock or posedge delete_isr_bit3) |
begin |
if (delete_isr_bit3) // Asynchronous reset |
isr_bit3_0[3] <= #`FF_DELAY 1'b0 ; |
else |
if (isr_int_prop && icr_bit3_0[3]) |
isr_bit3_0[3] <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge w_clock or posedge delete_isr_bit2) |
begin |
if (delete_isr_bit2) // Asynchronous reset |
isr_bit3_0[2] <= #`FF_DELAY 1'b0 ; |
else |
if (isr_err_int && icr_bit3_0[2]) |
isr_bit3_0[2] <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge w_clock or posedge delete_isr_bit1) |
begin |
if (delete_isr_bit1) // Asynchronous reset |
isr_bit3_0[1] <= #`FF_DELAY 1'b0 ; |
else |
if (isr_par_err_int && icr_bit3_0[1]) |
isr_bit3_0[1] <= #`FF_DELAY 1'b1 ; |
end |
always@(posedge w_clock or posedge delete_isr_bit0) |
begin |
if (delete_isr_bit0) // Asynchronous reset |
isr_bit3_0[0] <= #`FF_DELAY 1'b0 ; |
else |
if (isr_sys_err_int && icr_bit3_0[0]) |
isr_bit3_0[0] <= #`FF_DELAY 1'b1 ; |
end |
|
|
/*----------------------------------------------------------------------------------------------------------- |
OUTPUTs from registers !!! |
-----------------------------------------------------------------------------------------------------------*/ |
// PCI header outputs from command register |
assign serr_enable = command_bit8 ; |
assign perr_response = command_bit6 ; |
assign pci_master_enable = command_bit2_0[2] ; |
assign memory_space_enable = command_bit2_0[1] ; |
assign io_space_enable = command_bit2_0[0] ; |
// PCI header output from cache_line_size, latency timer and interrupt pin |
assign cache_line_size[7 : 0] = cache_line_size_reg ; |
assign latency_tim[7 : 0] = latency_timer ; |
assign int_pin[2 : 0] = r_interrupt_pin ; |
// PCI output from image registers |
assign pci_base_addr0[31 : 12] = pci_ba0_bit31_12 ; |
assign pci_base_addr1[31 : 12] = pci_ba1_bit31_12 ; |
assign pci_base_addr2[31 : 12] = pci_ba2_bit31_12 ; |
assign pci_base_addr3[31 : 12] = pci_ba3_bit31_12 ; |
assign pci_base_addr4[31 : 12] = pci_ba4_bit31_12 ; |
assign pci_base_addr5[31 : 12] = pci_ba5_bit31_12 ; |
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[31 : 12] = pci_am0 ; |
assign pci_addr_mask1[31 : 12] = pci_am1 ; |
assign pci_addr_mask2[31 : 12] = pci_am2 ; |
assign pci_addr_mask3[31 : 12] = pci_am3 ; |
assign pci_addr_mask4[31 : 12] = pci_am4 ; |
assign pci_addr_mask5[31 : 12] = pci_am5 ; |
assign pci_tran_addr0[31 : 12] = pci_ta0 ; |
assign pci_tran_addr1[31 : 12] = pci_ta1 ; |
assign pci_tran_addr2[31 : 12] = pci_ta2 ; |
assign pci_tran_addr3[31 : 12] = pci_ta3 ; |
assign pci_tran_addr4[31 : 12] = pci_ta4 ; |
assign pci_tran_addr5[31 : 12] = pci_ta5 ; |
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 ; |
// PCI output from pci error control and status register |
assign pci_error_en = pci_err_cs_bit0 ; |
assign pci_error_sig_set = pci_err_cs_bit8 ; |
assign pci_error_rty_exp_set = pci_err_cs_bit10 ; |
// WISHBONE output from image registers |
assign wb_base_addr0[31 : 12] = wb_ba0_bit31_12 ; |
assign wb_base_addr1[31 : 12] = wb_ba1_bit31_12 ; |
assign wb_base_addr2[31 : 12] = wb_ba2_bit31_12 ; |
assign wb_base_addr3[31 : 12] = wb_ba3_bit31_12 ; |
assign wb_base_addr4[31 : 12] = wb_ba4_bit31_12 ; |
assign wb_base_addr5[31 : 12] = wb_ba5_bit31_12 ; |
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[31 : 12] = wb_am0 ; |
assign wb_addr_mask1[31 : 12] = wb_am1 ; |
assign wb_addr_mask2[31 : 12] = wb_am2 ; |
assign wb_addr_mask3[31 : 12] = wb_am3 ; |
assign wb_addr_mask4[31 : 12] = wb_am4 ; |
assign wb_addr_mask5[31 : 12] = wb_am5 ; |
assign wb_tran_addr0[31 : 12] = wb_ta0 ; |
assign wb_tran_addr1[31 : 12] = wb_ta1 ; |
assign wb_tran_addr2[31 : 12] = wb_ta2 ; |
assign wb_tran_addr3[31 : 12] = wb_ta3 ; |
assign wb_tran_addr4[31 : 12] = wb_ta4 ; |
assign wb_tran_addr5[31 : 12] = wb_ta5 ; |
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 ; |
// WISHBONE output from wb error control and status register |
assign wb_error_en = wb_err_cs_bit0 ; |
assign wb_error_sig_set = wb_err_cs_bit10_8[8] ; |
assign wb_error_rty_exp_set = wb_err_cs_bit10_8[10] ; |
// 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 ; |
assign serr_int_en = icr_bit3_0[3] ; |
assign perr_int_en = icr_bit3_0[2] ; |
assign error_int_en = icr_bit3_0[1] ; |
assign int_prop_en = icr_bit3_0[0] ; |
|
|
endmodule |
|
/verilog/pci_parity_check.v
0,0 → 1,309
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "timescale.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_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_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 ; |
|
/*======================================================================================================================= |
Input and output data sampling - used by parity checking and generation logic |
=======================================================================================================================*/ |
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_include ; |
|
PAR_CBE_CRIT cbe_par_calc |
( |
.par_cbe_include_out(par_cbe_include), |
.par_cbe_out_in (par_cbe_out), |
.par_cbe_en_in (pci_cbe_en_in), |
.pci_cbe_in (pci_cbe_in_in) |
) ; |
|
reg cbe_par_reg ; |
always@( posedge reset_in or posedge clk_in ) |
begin |
if (reset_in) |
cbe_par_reg <= #`FF_DELAY 1'b0 ; |
else |
cbe_par_reg <= #`FF_DELAY par_cbe_include ; |
end |
|
/*======================================================================================================================= |
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. |
=======================================================================================================================*/ |
|
// 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 ; |
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 = cbe_par_reg ^^ data_in_par ; |
|
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 ; |
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 && ~pci_frame_en_in ; |
end |
|
// address phase parity indicator |
wire check_for_serr = ~pci_frame_reg_in && frame_dec2 ; |
wire serr_generate = check_for_serr && serr_enable_in && par_err_response_in ; |
|
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 |
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 ; |
|
// FF indicating that that last operation was done as bus master |
reg master_perr_report ; |
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
master_perr_report <= #`FF_DELAY 1'b0 ; |
else |
master_perr_report <= #`FF_DELAY pci_irdy_en_in ; |
end |
|
assign perr_mas_detect_out = master_perr_report && ( (par_err_response_in && perr_sampled) || pci_perr_en_reg ) ; |
|
endmodule |
/verilog/pci_target32_clk_en.v
0,0 → 1,108
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
|
`include "constants.v" |
`include "timescale.v" |
|
module PCI_TARGET32_CLK_EN |
( |
addr_phase, |
config_access, |
addr_claim_in, |
disconect_wo_data_in, |
pcir_fifo_data_err_in, |
rw_cbe0, |
pci_frame_in, |
pci_irdy_in, |
state_wait, |
state_transfere, |
state_backoff, |
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 disconect_wo_data_in ; // indicates disconnect without data termination from backend |
input pcir_fifo_data_err_in ; // indicates FIFO data error termination from backend |
input rw_cbe0 ; // registered (through all cycle) RW (CBE[0]) input signal from PCI bus |
input pci_frame_in ; // critical constrained input signal |
input pci_irdy_in ; // critical constrained input signal |
input state_wait ; // indicates WAIT state of FSM |
input state_transfere ; // indicates TRANSFERE state of FSM |
input state_backoff ; // indicates BACKOFF 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 && |
((disconect_wo_data_in && ~pci_irdy_in && ~pci_frame_in) || (pci_frame_in) || |
(~rw_cbe0 && pcir_fifo_data_err_in && ~pci_irdy_in && ~pci_frame_in)) ; |
|
// clock enable signal when FSM is in BACKOFF state |
wire s_bcko_clk_en = (state_backoff && 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 || s_bcko_clk_en) ; |
|
|
endmodule |
/verilog/top.v
0,0 → 1,359
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
`include "timescale.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, |
ACK_O, |
RTY_O, |
ERR_O, |
|
// WISHBONE master interface |
ADR_O, |
MDAT_I, |
MDAT_O, |
SEL_O, |
CYC_O, |
STB_O, |
WE_O, |
CAB_O, |
ACK_I, |
RTY_I, |
ERR_I |
); |
|
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 ; |
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 CAB_O ; |
input ACK_I ; |
input RTY_I ; |
input ERR_I ; |
|
|
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 |
.CLK_I(CLK_I), |
.RST_I(RST_I), |
.RST_O(RST_O), |
.INT_I(INT_I), |
.INT_O(INT_O), |
|
// WISHBONE slave interface |
.ADR_I(ADR_I), |
.SDAT_I(SDAT_I), |
.SDAT_O(SDAT_O), |
.SEL_I(SEL_I), |
.CYC_I(CYC_I), |
.STB_I(STB_I), |
.WE_I(WE_I), |
.CAB_I(CAB_I), |
.ACK_O(ACK_O), |
.RTY_O(RTY_O), |
.ERR_O(ERR_O), |
|
// WISHBONE master interface |
.ADR_O(ADR_O), |
.MDAT_I(MDAT_I), |
.MDAT_O(MDAT_O), |
.SEL_O(SEL_O), |
.CYC_O(CYC_O), |
.STB_O(STB_O), |
.WE_O(WE_O), |
.CAB_O(CAB_O), |
.ACK_I(ACK_I), |
.RTY_I(RTY_I), |
.ERR_I(ERR_I), |
|
// pci interface - system pins |
.PCI_CLK_IN (CLK), |
.PCI_RSTn_IN ( RST_in ), |
.PCI_RSTn_OUT ( RST_out ), |
.PCI_INTAn_IN ( INTA_in ), |
.PCI_INTAn_OUT( INTA_out), |
.PCI_RSTn_EN_OUT( RST_en), |
.PCI_INTAn_EN_OUT(INTA_en), |
|
// arbitration pins |
.PCI_REQn_OUT( REQ_out ), |
.PCI_REQn_EN_OUT ( REQ_en ), |
|
.PCI_GNTn_IN( GNT ), |
|
// protocol pins |
.PCI_FRAMEn_IN( FRAME_in), |
.PCI_FRAMEn_OUT( FRAME_out ), |
|
.PCI_FRAMEn_EN_OUT( FRAME_en ), |
.PCI_IRDYn_EN_OUT ( IRDY_en ), |
.PCI_DEVSELn_EN_OUT ( DEVSEL_en ), |
.PCI_TRDYn_EN_OUT ( TRDY_en ), |
.PCI_STOPn_EN_OUT ( STOP_en ), |
.PCI_AD_EN_OUT(AD_en), |
.PCI_CBEn_EN_OUT ( CBE_en) , |
|
.PCI_IRDYn_IN ( IRDY_in ), |
.PCI_IRDYn_OUT ( IRDY_out ), |
|
.PCI_IDSEL_IN ( IDSEL ), |
|
.PCI_DEVSELn_IN( DEVSEL_in ), |
.PCI_DEVSELn_OUT ( DEVSEL_out ), |
|
.PCI_TRDYn_IN ( TRDY_in ), |
.PCI_TRDYn_OUT ( TRDY_out ), |
|
.PCI_STOPn_IN( STOP_in ), |
.PCI_STOPn_OUT ( STOP_out ), |
|
// data transfer pins |
.PCI_AD_IN(AD_in), |
.PCI_AD_OUT (AD_out), |
|
.PCI_CBEn_IN( CBE_in ), |
.PCI_CBEn_OUT ( CBE_out ), |
|
// parity generation and checking pins |
.PCI_PAR_IN ( PAR_in ), |
.PCI_PAR_OUT ( PAR_out ), |
.PCI_PAR_EN_OUT ( PAR_en ), |
|
.PCI_PERRn_IN ( PERR_in ), |
.PCI_PERRn_OUT ( PERR_out ), |
.PCI_PERRn_EN_OUT ( PERR_en ), |
|
// system error pin |
.PCI_SERRn_OUT ( SERR_out ), |
.PCI_SERRn_EN_OUT ( SERR_en ) |
); |
|
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 ) ; |
|
endmodule |
/verilog/delayed_sync.v
0,0 → 1,442
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 "constants.v" |
`include "bus_commands.v" |
`include "timescale.v" |
module 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 |
synchronizer_flop 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 |
synchronizer_flop 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 |
|
synchronizer_flop 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 |
synchronizer_flop 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 |
|
synchronizer_flop rty_exp_back_prop_sync |
( |
.data_in (req_rty_exp_reg), |
.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 ; |
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/pciw_pcir_fifos.v
0,0 → 1,676
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "timescale.v" |
|
module 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, |
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_almost_full_out, |
pcir_full_out, |
pcir_almost_empty_out, |
pcir_empty_out, |
pcir_transaction_ready_out |
) ; |
|
/*----------------------------------------------------------------------------------------------------------- |
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 ; |
|
// status outputs |
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_almost_full_out = almost full output from PCIR_FIFO |
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_almost_full_out ; |
output pcir_full_out ; |
output pcir_almost_empty_out ; |
output pcir_empty_out ; |
output pcir_transaction_ready_out ; |
|
/*----------------------------------------------------------------------------------------------------------- |
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 ; |
|
// obvious |
wire vcc = 1'b1 ; |
wire gnd = 1'b0 ; |
|
/*----------------------------------------------------------------------------------------------------------- |
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 |
wire pcir_clear = reset_in || pcir_flush_in ; // PCIR_FIFO's clear signal |
|
`ifdef FPGA |
/*----------------------------------------------------------------------------------------------------------- |
this code is included only for FPGA core usage - somewhat different logic because of sharing |
one block selectRAM+ between two FIFOs |
-----------------------------------------------------------------------------------------------------------*/ |
`ifdef BIG |
/*----------------------------------------------------------------------------------------------------------- |
Big FPGAs |
PCIW_FIFO and PCIR_FIFO address prefixes - used for extending read and write addresses because of varible |
FIFO depth and fixed SelectRAM+ size. Addresses are zero paded on the left to form long enough address |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(7 - PCIW_ADDR_LENGTH):0] pciw_addr_prefix = {( 8 - PCIW_ADDR_LENGTH){1'b0}} ; |
wire [(7 - PCIR_ADDR_LENGTH):0] pcir_addr_prefix = {( 8 - PCIR_ADDR_LENGTH){1'b0}} ; |
|
// compose addresses |
wire [7:0] pciw_whole_waddr = {pciw_addr_prefix, pciw_waddr} ; |
wire [7:0] pciw_whole_raddr = {pciw_addr_prefix, pciw_raddr} ; |
|
wire [7:0] pcir_whole_waddr = {pcir_addr_prefix, pcir_waddr} ; |
wire [7:0] pcir_whole_raddr = {pcir_addr_prefix, pcir_raddr} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Only 8 bits out of 16 are used in ram3 and ram6 - wires for referencing them |
-----------------------------------------------------------------------------------------------------------*/ |
wire [15:0] dpram3_portB_output ; |
wire [15:0] dpram6_portA_output ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Control out assignements from ram3 output |
-----------------------------------------------------------------------------------------------------------*/ |
assign pciw_control_out = dpram3_portB_output[15:12] ; |
assign pcir_control_out = dpram6_portA_output[15:12] ; |
|
assign pciw_cbe_out = dpram3_portB_output[3:0] ; |
assign pcir_be_out = dpram6_portA_output[3:0] ; |
|
wire pciw_read_enable = pciw_rallow || pciw_empty ; |
wire pcir_read_enable = pcir_rallow || pcir_empty ; |
|
// Block SelectRAM+ cells instantiation |
RAMB4_S16_S16 dpram16_1 (.ADDRA(pciw_whole_waddr), .DIA(pciw_addr_data_in[15:0]), |
.ENA(vcc), .RSTA(reset_in), |
.CLKA(pci_clock_in), .WEA(pciw_wallow), |
.DOA(), |
.ADDRB(pciw_whole_raddr), .DIB(16'h0000), |
.ENB(pciw_read_enable), .RSTB(reset_in), |
.CLKB(wb_clock_in), .WEB(gnd), |
.DOB(pciw_addr_data_out[15:0])) ; |
|
RAMB4_S16_S16 dpram16_2 (.ADDRA(pciw_whole_waddr), .DIA(pciw_addr_data_in[31:16]), |
.ENA(vcc), .RSTA(reset_in), |
.CLKA(pci_clock_in), .WEA(pciw_wallow), |
.DOA(), |
.ADDRB(pciw_whole_raddr), .DIB(16'h0000), |
.ENB(pciw_read_enable), .RSTB(reset_in), |
.CLKB(wb_clock_in), .WEB(gnd), |
.DOB(pciw_addr_data_out[31:16])) ; |
|
RAMB4_S16_S16 dpram16_3 (.ADDRA(pciw_whole_waddr), .DIA({pciw_control_in, 8'h00, pciw_cbe_in}), |
.ENA(vcc), .RSTA(reset_in), |
.CLKA(pci_clock_in), .WEA(pciw_wallow), |
.DOA(), |
.ADDRB(pciw_whole_raddr), .DIB(16'h0000), |
.ENB(pciw_read_enable), .RSTB(reset_in), |
.CLKB(wb_clock_in), .WEB(gnd), |
.DOB(dpram3_portB_output)) ; |
|
RAMB4_S16_S16 dpram16_4 (.ADDRA(pcir_whole_raddr), .DIA(16'h0000), |
.ENA(pcir_read_enable), .RSTA(reset_in), |
.CLKA(pci_clock_in), .WEA(gnd), |
.DOA(pcir_data_out[15:0]), |
.ADDRB(pcir_whole_waddr), .DIB(pcir_data_in[15:0]), |
.ENB(vcc), .RSTB(reset_in), |
.CLKB(wb_clock_in), .WEB(pcir_wallow), |
.DOB()) ; |
|
RAMB4_S16_S16 dpram16_5 (.ADDRA(pcir_whole_raddr), .DIA(16'h0000), |
.ENA(pcir_read_enable), .RSTA(reset_in), |
.CLKA(pci_clock_in), .WEA(gnd), |
.DOA(pcir_data_out[31:16]), |
.ADDRB(pcir_whole_waddr), .DIB(pcir_data_in[31:16]), |
.ENB(vcc), .RSTB(reset_in), |
.CLKB(wb_clock_in), .WEB(pcir_wallow), |
.DOB()) ; |
|
RAMB4_S16_S16 dpram16_6 (.ADDRA(pcir_whole_raddr), .DIA(16'h0000), |
.ENA(pcir_read_enable), .RSTA(reset_in), |
.CLKA(pci_clock_in), .WEA(gnd), |
.DOA(dpram6_portA_output), |
.ADDRB(pcir_whole_waddr), .DIB({pcir_control_in, 8'h00, pcir_be_in}), |
.ENB(vcc), .RSTB(reset_in), |
.CLKB(wb_clock_in), .WEB(pcir_wallow), |
.DOB()) ; |
|
`else // SMALL FPGAs |
|
/*----------------------------------------------------------------------------------------------------------- |
Small FPGAs |
PCIW_FIFO and PCIR_FIFO address prefixes - used for extending read and write addresses because of varible |
FIFO depth and fixed SelectRAM+ size. Addresses are always paded, because of RAM sharing between FIFOs |
PCIW addresses are zero padded on the left, PCIR addresses are padded |
with ones on the left |
-----------------------------------------------------------------------------------------------------------*/ |
wire [(7 - PCIW_ADDR_LENGTH):0] pciw_addr_prefix = {( 8 - PCIW_ADDR_LENGTH){1'b0}} ; |
wire [(7 - PCIR_ADDR_LENGTH):0] pcir_addr_prefix = {( 8 - PCIR_ADDR_LENGTH){1'b1}} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Only 8 bits out of 16 are used in ram3 - wires for referencing them |
-----------------------------------------------------------------------------------------------------------*/ |
wire [15:0] dpram3_portA_output ; |
wire [15:0] dpram3_portB_output ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Control out assignements from ram3 output |
-----------------------------------------------------------------------------------------------------------*/ |
assign pciw_control_out = dpram3_portB_output[15:12] ; |
assign pcir_control_out = dpram3_portA_output[15:12] ; |
|
assign pciw_cbe_out = dpram3_portB_output[3:0] ; |
assign pcir_be_out = dpram3_portA_output[3:0] ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Logic used for extending port's enable input for one clock cycle to allow address and date change from |
PCI write fifo's write address and data back to PCI read fifo's address and data ( turnaround cycle ) |
-----------------------------------------------------------------------------------------------------------*/ |
reg pciw_write_performed ; |
always@(posedge pci_clock_in or posedge reset_in) |
begin |
if (reset_in) |
pciw_write_performed <= #`FF_DELAY 1'b0 ; |
else |
pciw_write_performed <= #`FF_DELAY pciw_wallow ; |
end |
|
/*----------------------------------------------------------------------------------------------------------- |
Logic used for extending port's enable input for one clock cycle to allow address and date change from |
PCI read fifo's write address and data back to PCI write fifo's address and data ( turnaround cycle ) |
-----------------------------------------------------------------------------------------------------------*/ |
reg pcir_write_performed ; |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) |
pcir_write_performed <= #`FF_DELAY 1'b0 ; |
else |
pcir_write_performed <= #`FF_DELAY pcir_wallow ; |
end |
|
/*----------------------------------------------------------------------------------------------------------- |
Additional register storing actual PCIW read address. It must be applied to port B during turnaround cycle |
-----------------------------------------------------------------------------------------------------------*/ |
reg [(PCIW_ADDR_LENGTH - 1):0] pciw_raddr_0 ; |
|
always@(posedge wb_clock_in or posedge pciw_clear) |
begin |
if (pciw_clear) |
pciw_raddr_0 <= #`FF_DELAY {PCIW_ADDR_LENGTH{1'b0}} ; |
else |
if(pciw_rallow) |
pciw_raddr_0 <= #`FF_DELAY pciw_raddr ; |
end |
|
wire [(PCIW_ADDR_LENGTH - 1):0] pciw_raddr_calc = pcir_write_performed ? pciw_raddr_0 : pciw_raddr ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Additional register storing actual PCIR read address. It must be applied to port A during turnaround cycle |
-----------------------------------------------------------------------------------------------------------*/ |
reg [(PCIR_ADDR_LENGTH - 1):0] pcir_raddr_0 ; |
|
always@(posedge pci_clock_in or posedge pcir_clear) |
begin |
if(pcir_clear) |
pcir_raddr_0 <= #`FF_DELAY {PCIR_ADDR_LENGTH{1'b0}} ; |
else |
if(pcir_rallow) |
pcir_raddr_0 <= #`FF_DELAY pcir_raddr ; |
end |
|
wire [(PCIR_ADDR_LENGTH - 1):0] pcir_raddr_calc = pciw_write_performed ? pcir_raddr_0 : pcir_raddr ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Port A and B enables |
-----------------------------------------------------------------------------------------------------------*/ |
wire portA_enable = pciw_wallow || pcir_rallow || pcir_empty || pciw_write_performed ; |
wire portB_enable = pcir_wallow || pciw_rallow || pciw_empty || pcir_write_performed ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Port A address generation for block SelectRam+ in SpartanII or Virtex |
Port A is clocked by PCI clock, DIA is input for pciw_fifo, DOA is output for pcir_fifo. Address is multiplexed |
between two values. |
Address multiplexing: |
pciw_wenable == 1 => ADDRA = pciw_waddr (write pointer of PCIW_FIFO) |
else ADDRA = pcir_raddr (read pointer of PCIR_FIFO) |
-----------------------------------------------------------------------------------------------------------*/ |
wire [7:0] portA_addr = pciw_wallow ? {pciw_addr_prefix, pciw_waddr} : {pcir_addr_prefix, pcir_raddr_calc} ; |
|
/*----------------------------------------------------------------------------------------------------------- |
Port B address generation for block SelectRam+ in SpartanII or Virtex |
Port B is clocked by PCI clock, DIB is input for pcir_fifo, DOB is output for pciw_fifo. Address is multiplexed |
between two values. |
Address multiplexing: |
pcir_wenable == 1 => ADDRB = pcir_waddr (write pointer of PCIR_FIFO) |
else ADDRB = pciw_raddr (read pointer of PCIW_FIFO) |
-----------------------------------------------------------------------------------------------------------*/ |
wire [7:0] portB_addr = pcir_wallow ? {pcir_addr_prefix, pcir_waddr} : {pciw_addr_prefix, pciw_raddr_calc} ; |
|
// Block SelectRAM+ cells instantiation |
RAMB4_S16_S16 dpram16_1 (.ADDRA(portA_addr), .DIA(pciw_addr_data_in[15:0]), |
.ENA(portA_enable), .RSTA(reset_in), |
.CLKA(pci_clock_in), .WEA(pciw_wallow), |
.DOA(pcir_data_out[15:0]), |
.ADDRB(portB_addr), .DIB(pcir_data_in[15:0]), |
.ENB(portB_enable), .RSTB(reset_in), |
.CLKB(wb_clock_in), .WEB(pcir_wallow), |
.DOB(pciw_addr_data_out[15:0])) ; |
|
RAMB4_S16_S16 dpram16_2 (.ADDRA(portA_addr), .DIA(pciw_addr_data_in[31:16]), |
.ENA(portA_enable), .RSTA(reset_in), |
.CLKA(pci_clock_in), .WEA(pciw_wallow), |
.DOA(pcir_data_out[31:16]), |
.ADDRB(portB_addr), .DIB(pcir_data_in[31:16]), |
.ENB(portB_enable), .RSTB(reset_in), |
.CLKB(wb_clock_in), .WEB(pcir_wallow), |
.DOB(pciw_addr_data_out[31:16])) ; |
|
RAMB4_S16_S16 dpram16_3 (.ADDRA(portA_addr), .DIA({pciw_control_in, 8'h00, pciw_cbe_in}), |
.ENA(portA_enable), .RSTA(reset_in), |
.CLKA(pci_clock_in), .WEA(pciw_wallow), |
.DOA(dpram3_portA_output), |
.ADDRB(portB_addr), .DIB({pcir_control_in, 8'h00, pcir_be_in}), |
.ENB(portB_enable), .RSTB(reset_in), |
.CLKB(wb_clock_in), .WEB(pcir_wallow), |
.DOB(dpram3_portB_output)) ; |
`endif |
|
|
|
|
|
`else |
wire [39:0] pciw_ram_data_out ; |
wire [39:0] pciw_ram_data_in = {pciw_control_in, pciw_cbe_in, pciw_addr_data_in} ; |
wire [39:0] pcir_ram_data_in = {pcir_control_in, pcir_be_in, pcir_data_in} ; |
wire [39:0] pcir_ram_data_out ; |
assign pciw_control_out = pciw_ram_data_out[39:36] ; |
assign pciw_cbe_out = pciw_ram_data_out[35:32] ; |
assign pciw_addr_data_out = pciw_ram_data_out [31:0] ; |
|
assign pcir_control_out = pcir_ram_data_out[39:36] ; |
assign pcir_be_out = pcir_ram_data_out[35:32] ; |
assign pcir_data_out = pcir_ram_data_out [31:0] ; |
|
`ifdef SYNCHRONOUS |
/*----------------------------------------------------------------------------------------------------------- |
ASIC memory primitives will be added here in the near future - currently there is only some generic, |
behavioral dual port ram here |
-----------------------------------------------------------------------------------------------------------*/ |
|
wire pciw_read_enable = pciw_rallow || pciw_empty ; |
wire pcir_read_enable = pcir_rallow || pcir_empty ; |
|
DP_SRAM #(PCIW_ADDR_LENGTH, PCIW_DEPTH) pciw_ram (.reset_in(reset_in), .wclock_in(pci_clock_in), .rclock_in(wb_clock_in), .data_in(pciw_ram_data_in), |
.raddr_in(pciw_raddr), .waddr_in(pciw_waddr), .data_out(pciw_ram_data_out), .renable_in(pciw_read_enable), .wenable_in(pciw_wallow)); |
|
DP_SRAM #(PCIR_ADDR_LENGTH, PCIR_DEPTH) pcir_ram (.reset_in(reset_in), .wclock_in(wb_clock_in), .rclock_in(pci_clock_in), .data_in(pcir_ram_data_in), |
.raddr_in(pcir_raddr), .waddr_in(pcir_waddr), .data_out(pcir_ram_data_out), .renable_in(pcir_read_enable), .wenable_in(pcir_wallow)); |
|
`else //ASYNCHRONOUS RAM |
DP_ASYNC_RAM #(PCIW_ADDR_LENGTH, PCIW_DEPTH) pciw_ram (.reset_in(reset_in), .wclock_in(pci_clock_in), .data_in(pciw_ram_data_in), |
.raddr_in(pciw_raddr), .waddr_in(pciw_waddr), .data_out(pciw_ram_data_out), .wenable_in(pciw_wallow)); |
|
DP_ASYNC_RAM #(PCIR_ADDR_LENGTH, PCIR_DEPTH) pcir_ram (.reset_in(reset_in), .wclock_in(wb_clock_in), .data_in(pcir_ram_data_in), |
.raddr_in(pcir_raddr), .waddr_in(pcir_waddr), .data_out(pcir_ram_data_out), .wenable_in(pcir_wallow)); |
`endif |
`endif |
|
/*----------------------------------------------------------------------------------------------------------- |
Instantiation of two control logic modules - one for PCIW_FIFO and one for PCIR_FIFO |
-----------------------------------------------------------------------------------------------------------*/ |
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), |
.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) |
); |
|
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), |
.almost_full_out(pcir_almost_full_out), |
.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]} ; |
|
wire in_count_en = pciw_wallow && pciw_last_in ; |
wire out_count_en = pciw_renable_in && pciw_last_out ; |
|
always@(posedge pci_clock_in or posedge pciw_clear) |
begin |
if (pciw_clear) |
begin |
inGreyCount[(PCIW_ADDR_LENGTH-2)] <= #`FF_DELAY 1'b1 ; |
inGreyCount[(PCIW_ADDR_LENGTH-3):0] <= #`FF_DELAY {(PCIW_ADDR_LENGTH-2),1'b0} ; |
end |
else |
if (in_count_en) |
inGreyCount <= #`FF_DELAY inNextGreyCount ; |
end |
|
always@(posedge wb_clock_in or posedge pciw_clear) |
begin |
if (pciw_clear) |
begin |
outGreyCount[(PCIW_ADDR_LENGTH-2)] <= #`FF_DELAY 1'b1 ; |
outGreyCount[(PCIW_ADDR_LENGTH-3):0] <= #`FF_DELAY {(PCIW_ADDR_LENGTH-2),1'b0} ; |
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 {(PCIW_ADDR_LENGTH-1){1'b0}} ; |
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 {(PCIW_ADDR_LENGTH-1){1'b0}} ; |
else |
if (out_count_en) |
pciw_outTransactionCount <= #`FF_DELAY pciw_outTransactionCount + 1'b1 ; |
end |
|
/*always@(posedge wb_clock_in or posedge pcir_clear) |
begin |
if (pcir_clear) |
pcir_inTransactionCount <= #`FF_DELAY 1'b0 ; |
else |
if (pcir_last_in && pcir_wallow) |
pcir_inTransactionCount <= #`FF_DELAY ~pcir_inTransactionCount ; |
end |
|
always@(posedge pci_clock_in or posedge pcir_clear) |
begin |
if (pcir_clear) |
pcir_outTransactionCount <= #`FF_DELAY 1'b0 ; |
else |
if (pcir_last_out) |
pcir_outTransactionCount <= #`FF_DELAY ~pcir_outTransactionCount ; |
end |
*/ |
|
reg pciw_transaction_ready_out ; |
always@(posedge wb_clock_in or posedge pciw_clear) |
begin |
if (pciw_clear) |
pciw_transaction_ready_out <= #`FF_DELAY 1'b0 ; |
else |
if ( out_count_en ) |
pciw_transaction_ready_out <= #`FF_DELAY 1'b0 ; |
else |
pciw_transaction_ready_out <= #`FF_DELAY inGreyCount != outGreyCount ; |
end |
|
assign pcir_transaction_ready_out = 1'b0 ; |
|
endmodule |
|
/verilog/pciw_fifo_control.v
0,0 → 1,482
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 |
// |
|
/* 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 "constants.v" |
`include "timescale.v" |
|
`ifdef FPGA |
// fifo design in FPGA will be synchronous |
`ifdef SYNCHRONOUS |
`else |
`define SYNCHRONOUS |
`endif |
`endif |
module PCIW_FIFO_CONTROL |
( |
rclock_in, |
wclock_in, |
renable_in, |
wenable_in, |
reset_in, |
flush_in, |
almost_full_out, |
full_out, |
almost_empty_out, |
empty_out, |
waddr_out, |
raddr_out, |
rallow_out, |
wallow_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; |
|
// flush input |
input flush_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 ; |
|
// two locations left output indicator |
output two_left_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_minus1 ; // current |
reg [(ADDR_LENGTH - 1):0] wgrey_addr ; // current |
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_minus3 ; // three before current |
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] ; |
|
// FFs for registered empty and full flags |
reg empty ; |
reg full ; |
|
// registered almost_empty and almost_full flags |
reg almost_empty ; |
reg almost_full ; |
|
// 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 ; |
|
// almost full output assignment |
assign almost_full_out = almost_full && ~full ; |
|
// clear generation for FFs and registers |
wire clear = reset_in || flush_in ; |
|
`ifdef SYNCHRONOUS |
|
reg wclock_nempty_detect ; |
always@(posedge reset_in or posedge wclock_in) |
begin |
if (reset_in) |
wclock_nempty_detect <= #`FF_DELAY 1'b0 ; |
else |
wclock_nempty_detect <= #`FF_DELAY (rgrey_addr != wgrey_addr) ; |
end |
|
// special synchronizing mechanism for different implementations - in synchronous imp., empty is prolonged for 1 clock edge if no write clock comes after initial write |
reg stretched_empty ; |
always@(posedge rclock_in or posedge clear) |
begin |
if(clear) |
stretched_empty <= #`FF_DELAY 1'b1 ; |
else |
stretched_empty <= #`FF_DELAY empty && ~wclock_nempty_detect ; |
end |
|
// empty output is actual empty + 1 read clock cycle ( stretched empty ) |
assign empty_out = empty || stretched_empty ; |
|
//rallow generation |
assign rallow = renable_in && ~empty && ~stretched_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 && ~empty && ~stretched_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 = empty_out ? raddr : raddr_plus_one ; |
|
// enable for this register |
wire raddr_plus_one_en = rallow ; |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
raddr_plus_one[(ADDR_LENGTH - 1):1] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0}} ; |
raddr_plus_one[0] <= #`FF_DELAY 1'b1 ; |
end |
else if (raddr_plus_one_en) |
raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ; |
end |
|
// raddr is filled with raddr_plus_one on rising read clock edge when rallow is high |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
// initial value is 000......00 |
raddr <= #`FF_DELAY { ADDR_LENGTH{1'b0}} ; |
else if (rallow) |
raddr <= #`FF_DELAY raddr_plus_one ; |
end |
|
`else |
// asynchronous RAM storage for FIFOs - somewhat simpler control logic |
//rallow generation |
assign rallow = renable_in && ~empty ; |
|
assign rallow_out = rallow; |
|
assign almost_empty_out = almost_empty && ~empty ; |
|
// read address counter - normal counter, nothing to it |
// for asynchronous implementation, there is no need for pointing to next address. |
// On clock edge that read is performed, read address will change and on the next clock edge |
// asynchronous memory will provide next data |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
// initial value is 000......00 |
raddr <= #`FF_DELAY { ADDR_LENGTH{1'b0}} ; |
else if (rallow) |
raddr <= #`FF_DELAY raddr + 1'b1 ; |
end |
|
assign empty_out = empty ; |
assign raddr_out = raddr ; |
`endif |
|
/*----------------------------------------------------------------------------------------------- |
Read address control consists of Read address counter and Grey Address pipeline |
There are 5 Grey addresses: |
- rgrey_minus3 is Grey Code of address three before current address |
- 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 code register for three before read address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......110 |
rgrey_minus3[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_minus3[(ADDR_LENGTH - 2):3] <= #`FF_DELAY { (ADDR_LENGTH - 4){1'b0} } ; |
rgrey_minus3[2:0] <= #`FF_DELAY 3'b110 ; |
end |
else |
if (rallow) |
rgrey_minus3 <= #`FF_DELAY rgrey_minus2 ; |
end |
|
// grey code register for two before read address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......010 |
rgrey_minus2[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_minus2[(ADDR_LENGTH - 2):2] <= #`FF_DELAY { (ADDR_LENGTH - 3){1'b0} } ; |
rgrey_minus2[1:0] <= #`FF_DELAY 2'b10 ; |
end |
else |
if (rallow) |
rgrey_minus2 <= #`FF_DELAY rgrey_minus1 ; |
end |
|
// grey code register for one before read address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......011 |
rgrey_minus1[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_minus1[(ADDR_LENGTH - 2):2] <= #`FF_DELAY { (ADDR_LENGTH - 3){1'b0} } ; |
rgrey_minus1[1:0] <= #`FF_DELAY 2'b11 ; |
end |
else |
if (rallow) |
rgrey_minus1 <= #`FF_DELAY rgrey_addr ; |
end |
|
// grey code register for read address - represents current Read Address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100.......01 |
rgrey_addr[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_addr[(ADDR_LENGTH - 2):1] <= #`FF_DELAY { (ADDR_LENGTH - 2){1'b0} } ; |
rgrey_addr[0] <= #`FF_DELAY 1'b1 ; |
end |
else |
if (rallow) |
rgrey_addr <= #`FF_DELAY rgrey_next ; |
end |
|
// grey code register for next read address - represents Grey Code of next read address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......00 |
rgrey_next[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_next[(ADDR_LENGTH - 2):0] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0} } ; |
end |
else |
if (rallow) |
rgrey_next <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ; |
end |
|
/*-------------------------------------------------------------------------------------------- |
Write address control consists of write address counter and three Grey Code Registers: |
- wgrey_minus1 holds grey coded address of one before current write address |
- wgrey_addr represents current Grey Coded write address |
- wgrey_next represents Grey Coded next write address |
----------------------------------------------------------------------------------------------*/ |
// grey code register for one before write address |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100.....001 |
wgrey_minus1[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
wgrey_minus1[(ADDR_LENGTH - 2):2] <= #`FF_DELAY { (ADDR_LENGTH - 3){1'b0} } ; |
wgrey_minus1[1:0] <= #`FF_DELAY 2'b11 ; |
end |
else |
if (wallow) |
wgrey_minus1 <= #`FF_DELAY wgrey_addr ; |
end |
|
// grey code register for write address |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100.....001 |
wgrey_addr[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
wgrey_addr[(ADDR_LENGTH - 2):1] <= #`FF_DELAY { (ADDR_LENGTH - 2){1'b0} } ; |
wgrey_addr[0] <= #`FF_DELAY 1'b1 ; |
end |
else |
if (wallow) |
wgrey_addr <= #`FF_DELAY wgrey_next ; |
end |
|
// grey code register for next write address |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......00 |
wgrey_next[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
wgrey_next[(ADDR_LENGTH - 2):0] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0} } ; |
end |
else |
if (wallow) |
wgrey_next <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ; |
end |
|
// write address counter - nothing special |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
// initial value 00.........00 |
waddr <= #`FF_DELAY { (ADDR_LENGTH){1'b0} } ; |
else |
if (wallow) |
waddr <= #`FF_DELAY waddr + 1'b1 ; |
end |
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Registered full control: |
registered full is set on rising edge of wclock_in, when one location is left in fifo and another is written |
It's kept high until something is read from FIFO, which is registered on |
next rising write clock edge. |
|
Registered almost full control: |
registered almost full is set on rising edge of write clock when two locations are left in fifo and another is written to it. |
it's kept high until something is read/written from/to fifo |
|
Registered two left control: |
registered two left is set on rising edge of write clock when three locations are left in fifo and another is written to it. |
it's kept high until something is read/written from/to fifo. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
reg two_left_out ; |
wire comb_full = wgrey_next == rgrey_addr ; |
wire comb_almost_full = wgrey_addr == rgrey_minus2 ; |
wire comb_two_left = wgrey_next == rgrey_minus2 ; |
wire comb_three_left = wgrey_next == rgrey_minus3 ; |
|
//combinatorial input to Registered full FlipFlop |
wire reg_full = (wallow && comb_almost_full) || (comb_full) ; |
|
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
full <= #`FF_DELAY 1'b0 ; |
else |
full <= #`FF_DELAY reg_full ; |
end |
|
// input for almost full flip flop |
wire reg_almost_full_in = wallow && comb_two_left || comb_almost_full ; |
|
always@(posedge clear or posedge wclock_in) |
begin |
if (clear) |
almost_full <= #`FF_DELAY 1'b0 ; |
else |
almost_full <= #`FF_DELAY reg_almost_full_in ; |
end |
|
wire reg_two_left_in = wallow && comb_three_left || comb_two_left ; |
|
always@(posedge clear or posedge wclock_in) |
begin |
if (clear) |
two_left_out <= #`FF_DELAY 1'b0 ; |
else |
two_left_out <= #`FF_DELAY reg_two_left_in ; |
end |
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Registered empty control: |
registered empty is set on rising edge of rclock_in, |
when only one location is used in and read from fifo. It's kept high until something is written to FIFO, which is registered on |
the next read clock. |
|
Registered almost empty control: |
almost empty is set on rising clock edge of rclock when two locations are used and one read from FIFO. It's kept high until |
something is read/written from/to fifo. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
wire comb_almost_empty = rgrey_next == wgrey_addr ; |
wire comb_empty = rgrey_addr == wgrey_addr ; |
wire comb_two_used = rgrey_next == wgrey_minus1 ; |
|
// combinatorial input for registered emty FlipFlop |
wire reg_empty = (rallow && comb_almost_empty) || comb_empty ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
empty <= #`FF_DELAY 1'b1 ; |
else |
empty <= #`FF_DELAY reg_empty ; |
end |
|
// input for almost empty flip flop |
wire reg_almost_empty = rallow && comb_two_used || comb_almost_empty ; |
always@(posedge clear or posedge rclock_in) |
begin |
if (clear) |
almost_empty <= #`FF_DELAY 1'b0 ; |
else |
almost_empty <= #`FF_DELAY reg_almost_empty ; |
end |
|
endmodule |
/verilog/decoder.v
0,0 → 1,158
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "timescale.v" |
|
module 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_target32_load_crit.v
0,0 → 1,84
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: pci_target32_load_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.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 |
|
`include "constants.v" |
`include "timescale.v" |
|
module PCI_TARGET32_LOAD_CRIT |
( |
tar_load_out_w, |
tar_load_out_w_irdy, |
load_med_reg_w, |
load_med_reg_w_irdy, |
pci_irdy_in, |
pci_target_load_out, |
load_medium_reg_out |
); |
|
input tar_load_out_w ; // target load signal (composed without critical signals) that don't need critical inputs |
input tar_load_out_w_irdy ; // target load signal (composed without critical signals) that needs AND with critical |
// IRDY input |
input load_med_reg_w ; // load reg signal (composed without critical signals) that don't need critical inputs |
input load_med_reg_w_irdy ; // load reg signal (composed without critical signals) that needs AND with critical |
// IRDY input |
input pci_irdy_in ; // critical constrained input signal |
|
output pci_target_load_out ; // pci target load output |
output load_medium_reg_out ; // load medium register output |
|
// pci target load output with preserved hierarchy for minimum delay! |
assign pci_target_load_out = (tar_load_out_w || (tar_load_out_w_irdy && ~pci_irdy_in)) ; |
// load medium register output with preserved hierarchy for minimum delay! |
assign load_medium_reg_out = (load_med_reg_w || (load_med_reg_w_irdy && ~pci_irdy_in)) ; |
|
|
endmodule |
/verilog/pci_master32_sm_if.v
0,0 → 1,766
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "bus_commands.v" |
`include "timescale.v" |
|
/*==================================================================== |
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, |
werror_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_pending_in, |
err_rty_exp_out, |
|
cache_line_size_in, |
|
// two signals for pci control and status |
mabort_received_out, |
tabort_received_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, |
werror_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 err_pending_in ; |
|
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 |
|
|
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 || err_pending_in ; |
|
// 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 ; |
|
// 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) |
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 ; |
source_be = ~del_be_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 && wtransfer_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 [31:2] 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 [8: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 [8:0] read_count ; |
|
// cache line bound indicator - it signals when data for one complete cacheline was read |
wire read_bound_comb = ~|(read_count[8:2]) ; |
reg read_bound ; |
always@(posedge clk_in) |
begin |
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 clk_in) |
begin |
if (reset_in) |
read_count <= #`FF_DELAY 8'h00 ; |
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 |
|
// 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_load_slow = (req_out && ~rdy_out) && (del_read_req || write_req_int) ; |
wire data_load_en = posted_write_req && ~last_out && ~wait_in ; |
wire data_be_load = data_load_slow || (data_load_en && wtransfer_in) ; |
|
wire last_load = req_out && ( ~rdy_out || ~wait_in && wtransfer_in ) ; |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if (reset_in) |
begin |
be_out <= #`FF_DELAY 4'hF ; |
data_out <= #`FF_DELAY 32'h0000_0000 ; |
end |
else |
if ( data_be_load ) |
begin |
data_out <= #`FF_DELAY next_data_out ; |
be_out <= #`FF_DELAY next_be_out ; |
end |
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/bus_commands.v
0,0 → 1,69
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
// definitions of PCI bus commands |
`define BC_IACK 4'h0 //used |
`define BC_SPECIAL 4'h1 //not used |
`define BC_IO_READ 4'h2 //used |
`define BC_IO_WRITE 4'h3 //used |
`define BC_RESERVED0 4'h4 //not used |
`define BC_RESERVED1 4'h5 //not used |
`define BC_MEM_READ 4'h6 //used |
`define BC_MEM_WRITE 4'h7 //used |
`define BC_RESERVED2 4'h8 //not used |
`define BC_RESERVED3 4'h9 //not used |
`define BC_CONF_READ 4'hA //used |
`define BC_CONF_WRITE 4'hB //used |
`define BC_MEM_READ_MUL 4'hC //used |
`define BC_DUAL_ADDR_CYC 4'hD //not used |
`define BC_MEM_READ_LN 4'hE //used |
`define BC_MEM_WRITE_INVAL 4'hF //not used |
|
// common bits for configuration cycle commands |
`define BC_CONF_RW 3'b101 |
/verilog/frame_load_crit.v
0,0 → 1,73
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
|
`include "timescale.v" |
|
// This one is used in master state machine for frame output flip flop clock enable driving |
module 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/constants.v
0,0 → 1,274
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
|
//////////////////////////////////////////////////////////////////////// |
//// //// |
//// FIFO parameters define behaviour of FIFO control logic and //// |
//// FIFO depths. //// |
//// //// |
//////////////////////////////////////////////////////////////////////// |
|
// FPGA implementation definitions : |
// FPGA definition is optional - if it's defined, BLOCK SelectRam+ will |
// be used for FIFO storage space. Implementation is SYNCHRONOUS regardles |
// of SYNCHRONOUS parameter definition. Smallest FPGA must have at leat 6 |
// block select rams available. For bigger FPGAs, there is possibility of |
// defining BIG - only for FPGAs with 12 or more available block rams |
// Defining FPGA without BIG limits any FIFO to max depth of 128 ( address |
// length 7). Large FPGAs with BIG definition provide max 256 ( address length |
// 8) depth for each FIFO. FIFO depth MUST be power of 2, so address length can |
// be defined |
// Minimum FIFO depth of any FIFO is 8 - control logic is such that address |
// lengths less than 3 are not supported |
`define FPGA |
`define WBW_DEPTH 16 |
`define WBW_ADDR_LENGTH 4 |
`define WBR_DEPTH 32 |
`define WBR_ADDR_LENGTH 5 |
`define PCIW_DEPTH 32 |
`define PCIW_ADDR_LENGTH 5 |
`define PCIR_DEPTH 32 |
`define PCIR_ADDR_LENGTH 5 |
//`define BIG |
|
// if FPGA is not defined (commented out), there can still be control logic |
// for synchronous rams used by defining SYNCHRONOUS |
`define SYNCHRONOUS |
|
// if neither FPGA or SYNCRONOUS are defined, control logic for asynchronous |
// rams is included |
|
|
// control bus encoding definitions |
`define ADDRESS 4'h8 // address entry |
`define LAST 4'h1 // last data entry in transaction |
`define DATA_ERROR 4'h2 // data was read with error signaled |
`define DATA 4'h0 // intermediate data beat in a burst |
|
// 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 |
|
// Flip flop delay included in assignements to every register |
`define FF_DELAY 2 // FF propagation delay |
|
`timescale 1ns/10ps |
|
// PCI bridge HOST/GUEST implentation |
// - for HOST implementation 'HOST' MUST be written othervise there is GUEST |
// implementation and 'GUEST MUST be written !!! |
`define HOST |
|
// 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 |
|
// 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 |
|
// no. of PCI Target IMAGES |
// - 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_IMAGE6 (and `define HOST), we assign PCI_IMAGE0 |
// to normal WB to PCI image and not to configuration space! |
`define PCI_IMAGE6 |
|
`define PCI_AM0 20'hffff_f |
`define PCI_AM1 20'hffff_f |
`define PCI_AM2 20'hffff_f |
`define PCI_AM3 20'hffff_f |
`define PCI_AM4 20'hffff_f |
`define PCI_AM5 20'hffff_f |
// no. of WISHBONE Slave IMAGES |
// - 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. |
`define WB_IMAGE5 |
|
`define WB_AM0 20'hffff_f |
// if WB_CNF_IMAGE is commented out, than access to configuration space from WISHBONE for GUEST bridges is disabled alltogether ( even read only ) |
//`define WB_CNF_IMAGE |
|
// 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 the decode speed, faster the WISHBONE clock can be |
`define WB_DECODE_FAST |
//`define WB_DECODE_MEDIUM |
//`define WB_DECODE_SLOW |
|
// definition of how many address lines are compared on address decoding for WISHBONE and PCI images. Put a number of smallest image used here. |
// Minimum number is 1 and maximum number is 20 ( 1 = only 2GB images can be done, 20 - 4KB image is smallest possible) |
`define WB_NUM_OF_DEC_ADDR_LINES 20 |
`define PCI_NUM_OF_DEC_ADDR_LINES 20 |
|
// Configuration space base address for accesses from WISHBONE bus |
`define WB_CONFIGURATION_BASE 20'hCCCC_C |
|
// PCI target & WB slave ADDRESS names for configuration space !!! |
// 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 |
`define P_BA0_ADDR 6'h01 // = PCI_CONF_SPC_BAR |
`define P_AM0_ADDR 6'h02 |
`define P_TA0_ADDR 6'h03 |
`define P_IMG_CTRL1_ADDR 6'h04 |
`define P_BA1_ADDR 6'h05 |
`define P_AM1_ADDR 6'h06 |
`define P_TA1_ADDR 6'h07 |
`define P_IMG_CTRL2_ADDR 6'h08 |
`define P_BA2_ADDR 6'h09 |
`define P_AM2_ADDR 6'h0a |
`define P_TA2_ADDR 6'h0b |
`define P_IMG_CTRL3_ADDR 6'h0c |
`define P_BA3_ADDR 6'h0d |
`define P_AM3_ADDR 6'h0e |
`define P_TA3_ADDR 6'h0f |
`define P_IMG_CTRL4_ADDR 6'h10 |
`define P_BA4_ADDR 6'h11 |
`define P_AM4_ADDR 6'h12 |
`define P_TA4_ADDR 6'h13 |
`define P_IMG_CTRL5_ADDR 6'h14 |
`define P_BA5_ADDR 6'h15 |
`define P_AM5_ADDR 6'h16 |
`define P_TA5_ADDR 6'h17 |
`define P_ERR_CS_ADDR 6'h18 |
`define P_ERR_ADDR_ADDR 6'h19 |
`define P_ERR_DATA_ADDR 6'h1a |
|
`define WB_CONF_SPC_BAR_ADDR 6'h20 |
`define W_IMG_CTRL1_ADDR 6'h21 |
`define W_BA1_ADDR 6'h22 |
`define W_AM1_ADDR 6'h23 |
`define W_TA1_ADDR 6'h24 |
`define W_IMG_CTRL2_ADDR 6'h25 |
`define W_BA2_ADDR 6'h26 |
`define W_AM2_ADDR 6'h27 |
`define W_TA2_ADDR 6'h28 |
`define W_IMG_CTRL3_ADDR 6'h29 |
`define W_BA3_ADDR 6'h2a |
`define W_AM3_ADDR 6'h2b |
`define W_TA3_ADDR 6'h2c |
`define W_IMG_CTRL4_ADDR 6'h2d |
`define W_BA4_ADDR 6'h2e |
`define W_AM4_ADDR 6'h2f |
`define W_TA4_ADDR 6'h30 |
`define W_IMG_CTRL5_ADDR 6'h31 |
`define W_BA5_ADDR 6'h32 |
`define W_AM5_ADDR 6'h33 |
`define W_TA5_ADDR 6'h34 |
`define W_ERR_CS_ADDR 6'h35 |
`define W_ERR_ADDR_ADDR 6'h36 |
`define W_ERR_DATA_ADDR 6'h37 |
`define CNF_ADDR_ADDR 6'h38 |
// Following two registers are not implemented in a configuration space but in a WishBone unit! |
`define CNF_DATA_ADDR 6'h39 |
`define INT_ACK_ADDR 6'h3a |
// ------------------------------------ |
`define ICR_ADDR 6'h3b |
`define ISR_ADDR 6'h3c |
|
// the width of the registers |
`define REG_WIDTH 32 |
|
// timing delays |
`define DLY_L1 1 |
`define DLY_L2 2 |
`define DLY_L3 3 |
`define DLY_L4 4 |
`define DLY_L5 5 |
|
/*----------------------------------------------------------------------------------------------------------- |
Core speed definition - used for simulation and bit in header register indicating 66MHz capable |
defice |
-----------------------------------------------------------------------------------------------------------*/ |
|
`define PCI33 |
// define PCI66 |
|
/*----------------------------------------------------------------------------------------------------------- |
[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. |
66MHz goes into 66MHz capable bit and indicates that device can operate on 66MHz PCI bus. |
-----------------------------------------------------------------------------------------------------------*/ |
`define HEADER_DEVICE_ID 16'h0001 |
`define HEADER_VENDOR_ID 16'h2321 |
`define HEADER_REVISION_ID 8'h01 |
|
`ifdef PCI33 |
`define HEADER_66MHz 1'b0 |
`else |
`ifdef PCI66 |
`define HEADER_66MHz 1'b1 |
`endif |
`endif |
|
// Implement address translation or not |
`define ADDR_TRAN_IMPL |
|
/*----------------------------------------------------------------------------------------------------------- |
WISHBONE clock is specified in frequency in GHz |
-----------------------------------------------------------------------------------------------------------*/ |
`define WB_FREQ 0.1 |
/verilog/pci_target32_stop_crit.v
0,0 → 1,79
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
|
`include "constants.v" |
`include "timescale.v" |
|
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/cur_out_reg.v
0,0 → 1,261
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "timescale.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 CUR_OUT_REG |
( |
reset_in, |
clk_in, |
frame_in, |
frame_load_in, |
irdy_in, |
devsel_in, |
trdy_in, |
trdy_en_in, |
stop_in, |
master_load_in, |
target_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, |
|
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 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 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 ; |
tar_ad_en_out<= #`FF_DELAY tar_ad_en_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 ( master_load_in ) |
cbe_out <= #`FF_DELAY cbe_in ; |
|
end |
|
wire data_load = master_load_in || target_load_in ; |
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 ( data_load ) |
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/delayed_write_reg.v
0,0 → 1,83
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "timescale.v" |
|
module 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/serr_en_crit.v
0,0 → 1,73
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
|
`include "timescale.v" |
|
module 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/irdy_out_crit.v
0,0 → 1,73
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
|
`include "timescale.v" |
// This module is used in master state machine for IRDY output driving |
|
module 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/pci_target_unit.v
0,0 → 1,816
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 "constants.v" |
`include "timescale.v" |
|
module PCI_TARGET_UNIT |
( |
reset_in, |
wb_clock_in, |
pci_clock_in, |
ADR_O, |
MDATA_O, |
MDATA_I, |
CYC_O, |
STB_O, |
WE_O, |
SEL_O, |
ACK_I, |
RTY_I, |
ERR_I, |
CAB_O, |
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_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_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_bckp_trdy_en_in, |
pciu_pciif_bckp_devsel_in, |
pciu_pciif_bckp_trdy_in, |
pciu_pciif_bckp_stop_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_pciif_target_load_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_err_pending_in, |
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 |
); |
|
input reset_in, |
wb_clock_in, |
pci_clock_in ; |
|
output [31:0] ADR_O ; |
output [31:0] MDATA_O ; |
input [31:0] MDATA_I ; |
output CYC_O ; |
output STB_O ; |
output WE_O ; |
output [3:0] SEL_O ; |
input ACK_I ; |
input RTY_I ; |
input ERR_I ; |
output CAB_O ; |
|
input pciu_wbw_fifo_empty_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 [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar0_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar1_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar2_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar3_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar4_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_bar5_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am0_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am1_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am2_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am3_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am4_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_am5_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta0_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta1_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta2_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta3_in ; |
input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pciu_ta4_in ; |
input [(`WB_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_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 pciu_pciif_bckp_trdy_en_in ; |
input pciu_pciif_bckp_devsel_in ; |
input pciu_pciif_bckp_trdy_in ; |
input pciu_pciif_bckp_stop_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_pciif_target_load_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 ; |
input pciu_err_pending_in ; |
|
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 ; |
|
|
// 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_target_load_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 pcit_sm_req_out ; |
wire pcit_sm_rdy_out ; |
wire pcit_sm_addr_phase_out ; |
wire pcit_sm_bckp_trdy_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_pciif_target_load_out = pcit_sm_target_load_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_pciw_fifo_full_out ; |
wire pcit_if_pcir_fifo_data_err_out ; |
wire pcit_if_wbw_fifo_empty_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_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_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_read_rty_cnt_exp_out ; |
wire wbm_sm_cyc_out ; |
wire wbm_sm_stb_out ; |
wire wbm_sm_we_out ; |
wire [3:0] wbm_sm_sel_out ; |
wire [31:0] wbm_sm_adr_out ; |
wire [31:0] wbm_sm_mdata_out ; |
wire wbm_sm_cab_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_write_rty_cnt_exp_out ; // only for writing to WB ! |
assign pciu_err_rty_exp_out = wbm_sm_write_rty_cnt_exp_out ; |
|
assign ADR_O = wbm_sm_adr_out ; |
assign MDATA_O = wbm_sm_mdata_out ; |
assign CYC_O = wbm_sm_cyc_out ; |
assign STB_O = wbm_sm_stb_out ; |
assign WE_O = wbm_sm_we_out ; |
assign SEL_O = wbm_sm_sel_out ; |
assign CAB_O = wbm_sm_cab_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_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 = fifos_pciw_empty_out ; |
|
// 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_full_out ; |
wire fifos_pcir_full_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_prefetch_en = del_sync_burst_out ; |
wire [7:0] wbm_sm_pci_cache_line_size = pciu_cache_line_size_in ; |
wire wbm_sm_pcir_fifo_almost_full_in = fifos_pcir_almost_full_out ; |
wire wbm_sm_pcir_fifo_full_in = fifos_pcir_full_out ; |
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 wbm_sm_pci_error_sig_set_in = pciu_err_pending_in ; |
wire [31:0] wbm_sm_mdata_in = MDATA_I ; |
wire wbm_sm_ack_in = ACK_I ; |
wire wbm_sm_rty_in = RTY_I ; |
wire wbm_sm_err_in = ERR_I ; |
|
// WISHBONE master interface instantiation |
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_prefetch_en (wbm_sm_pci_tar_prefetch_en), //in |
.pci_cache_line_size (wbm_sm_pci_cache_line_size), //in |
.wb_read_done (wbm_sm_wb_read_done), //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), |
.pcir_fifo_almost_full_in (wbm_sm_pcir_fifo_almost_full_in), |
.pcir_fifo_full_in (wbm_sm_pcir_fifo_full_in), |
.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_set_in (wbm_sm_pci_error_sig_set_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), |
.read_rty_cnt_exp_out (wbm_sm_read_rty_cnt_exp_out), |
.CYC_O (wbm_sm_cyc_out), |
.STB_O (wbm_sm_stb_out), |
.WE_O (wbm_sm_we_out), |
.SEL_O (wbm_sm_sel_out), |
.ADR_O (wbm_sm_adr_out), |
.MDATA_I (wbm_sm_mdata_in), |
.MDATA_O (wbm_sm_mdata_out), |
.ACK_I (wbm_sm_ack_in), |
.RTY_I (wbm_sm_rty_in), |
.ERR_I (wbm_sm_err_in), |
.CAB_O (wbm_sm_cab_out) |
); |
|
// 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 ; |
|
// 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 |
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), |
.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_almost_full_out (fifos_pcir_almost_full_out), |
.pcir_full_out (fifos_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 () |
) ; |
|
// 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_out ; |
wire del_sync_retry_expired_in = wbm_sm_read_rty_cnt_exp_out ; |
|
// delayed transaction logic instantiation |
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 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_trdy_in = pcit_sm_bckp_trdy_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_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 [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 [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr0_in = pciu_bar0_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr1_in = pciu_bar1_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr2_in = pciu_bar2_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr3_in = pciu_bar3_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr4_in = pciu_bar4_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_base_addr5_in = pciu_bar5_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask0_in = pciu_am0_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask1_in = pciu_am1_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask2_in = pciu_am2_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask3_in = pciu_am3_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask4_in = pciu_am4_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_addr_mask5_in = pciu_am5_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_tran_addr0_in = pciu_ta0_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_tran_addr1_in = pciu_ta1_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_tran_addr2_in = pciu_ta2_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_tran_addr3_in = pciu_ta3_in ; |
wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] pcit_if_pci_tran_addr4_in = pciu_ta4_in ; |
wire [(`WB_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), |
.req_in (pcit_if_req_in), |
.rdy_in (pcit_if_rdy_in), |
.addr_phase_in (pcit_if_addr_phase_in), |
.bckp_trdy_in (pcit_if_bckp_trdy_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), |
.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), |
.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_out (pcit_if_burst_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_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), |
.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 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_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_frame_en_in = pciu_wbu_frame_en_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), |
.pci_target_load_out (pcit_sm_target_load_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), |
.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), |
.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), |
.req_out (pcit_sm_req_out), |
.rdy_out (pcit_sm_rdy_out), |
.addr_phase_out (pcit_sm_addr_phase_out), |
.bckp_trdy_out (pcit_sm_bckp_trdy_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), |
.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_frame_en_in (pcit_sm_wbu_frame_en_in) |
) ; |
|
endmodule |
/verilog/io_mux_en_mult.v
0,0 → 1,68
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "io_mux_en_mult.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.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// this module is provided for downsizing fanout of critical logic cells, which use heavily constrained |
// pci inputs - it is used for AD lines output enable flip flops driven by both master and target |
|
`include "timescale.v" |
|
module IO_MUX_EN_MULT |
( |
mas_ad_en_in, |
tar_ad_en_in, |
ad_en_out |
); |
|
input mas_ad_en_in ; |
input tar_ad_en_in ; |
output ad_en_out ; |
|
assign ad_en_out = mas_ad_en_in || tar_ad_en_in ; |
|
endmodule |
/verilog/conf_cyc_addr_dec.v
0,0 → 1,109
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
|
`include "constants.v" |
`include "timescale.v" |
|
module 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_master32_sm.v
0,0 → 1,601
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
// module includes pci master state machine and surrounding logic |
`include "bus_commands.v" |
`include "constants.v" |
`include "timescale.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, |
load_next_out, |
wait_out, |
wtransfer_out, |
rtransfer_out, |
retry_out, |
werror_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 |
werror_out, // error output - when 1 indicates that error (target abort) occured on current dataphase - heavy constraints |
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 load_next_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 [4:0] next_state ; |
// SM state register |
reg [4: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_timer_enable = sm_data_phases ; |
wire latency_timer_load = ~sm_address && ~sm_data_phases ; |
wire latency_timer_exp = ~( |
(latency_timer[7] || latency_timer[6] || latency_timer[5] || latency_timer[4]) || |
(latency_timer[3] || latency_timer[2] || latency_timer_load) |
) ; |
|
// flip flop for registering latency timer timeout |
reg latency_time_out ; |
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
latency_time_out <= #`FF_DELAY 1'b0 ; |
else |
latency_time_out <= #`FF_DELAY latency_timer_exp ; |
end |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
latency_timer <= #`FF_DELAY 8'hFF ; |
else |
if ( latency_timer_load ) |
latency_timer <= #`FF_DELAY latency_tim_val_in ; |
else |
if ( latency_timer_enable && ~latency_time_out) // 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 || timeout || (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) |
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 |
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 |
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) ; |
|
// current error status - calculated directly from target signals and therefore critical |
assign werror_out = (~pci_stop_in && pci_devsel_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 load_force = (sm_idle && u_have_pci_bus) || sm_address ; |
|
// next data loading is allowed when state machine is in transfer state and operation is a write |
wire load_allow = sm_data_phases && do_write ; |
|
// actual loading during data phases is done by monitoring critical target response signals - separate module |
MAS_LOAD_NEXT_CRIT ad_iob_ce |
( |
.load_next_out (load_next_out), |
.load_force_in (load_force), |
.load_allow_in (load_allow), |
.pci_trdy_in (pci_trdy_in) |
) ; |
|
// 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 |
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) ; |
|
// critical timing ad enable - calculated from target response inputs |
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_keep_in (ad_en_keep), |
.pci_stop_in (pci_stop_in), |
.pci_trdy_in (pci_trdy_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 |
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 |
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 ; |
end |
|
S_ADDRESS: begin |
// indicate the state |
sm_address = 1'b1 ; |
// select appropriate data/be for outputs |
wdata_selector = SEL_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 |
always@(wdata_selector or address_in or bc_in or data_in or be_in or next_data_in or next_be_in) |
begin |
case ( wdata_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/cbe_en_crit.v
0,0 → 1,72
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
`include "timescale.v" |
module 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/frame_en_crit.v
0,0 → 1,74
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
|
`include "timescale.v" |
|
// This one is used in master state machine for frame output enable driving |
|
module 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_in_reg.v
0,0 → 1,156
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "timescale.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! |
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 ; |
end |
end |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
pci_ad_reg_out <= #`FF_DELAY 32'h0000_0000 ; |
else |
pci_ad_reg_out <= #`FF_DELAY pci_ad_in ; |
end |
|
always@(posedge reset_in or posedge clk_in) |
begin |
if ( reset_in ) |
pci_cbe_reg_out <= #`FF_DELAY 4'h0 ; |
else |
pci_cbe_reg_out <= #`FF_DELAY pci_cbe_in ; |
end |
|
|
endmodule |
/verilog/mas_load_next_crit.v
0,0 → 1,73
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "mas_load_next_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.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 driving clock enable of AD output flip flops |
`include "timescale.v" |
|
module MAS_LOAD_NEXT_CRIT |
( |
load_next_out, |
load_force_in, |
load_allow_in, |
pci_trdy_in |
) ; |
|
output load_next_out ; |
input load_force_in, |
load_allow_in, |
pci_trdy_in ; |
|
//wire load_force = (sm_idle_in && u_have_pci_bus_in) || sm_address_in ; |
//wire load_allow = sm_data_phases_in && do_write_in ; |
|
assign load_next_out = load_force_in || load_allow_in && ~pci_trdy_in ; |
endmodule |
/verilog/pci_decoder.v
0,0 → 1,168
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "timescale.v" |
|
module PCI_DECODER (hit, addr_out, addr_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 |
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 ; |
|
// 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) ; |
|
assign hit = (addr_hit && space_hit) ; |
|
/*----------------------------------------------------------------------------------------------------------- |
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/wb_slave_unit.v
0,0 → 1,800
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 "constants.v" |
`include "timescale.v" |
module 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_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_err_pending_in, |
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_pciif_load_next_out |
); |
|
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 [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 ; |
input wbu_err_pending_in ; |
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_pciif_load_next_out ; |
|
// 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_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_load_next_out ; |
|
wire pcim_sm_wait_out ; |
wire pcim_sm_wtransfer_out ; |
wire pcim_sm_rtransfer_out ; |
wire pcim_sm_retry_out ; |
wire pcim_sm_werror_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 ; |
|
// 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_pciif_load_next_out = pcim_sm_load_next_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 ; |
|
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 ; |
|
assign wbu_wbw_fifo_empty_out = fifos_wbw_empty_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 || wbu_err_pending_in ; |
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 |
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), |
.del_in_progress_out (wbs_sm_del_in_progress_out), |
.ccyc_addr_in (wbs_sm_ccyc_addr_in), |
.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 ; |
|
// 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 |
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), |
.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) |
) ; |
|
wire [31:0] amux_addr_in = ADDR_I ; |
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 ; |
|
WB_ADDR_MUX wb_addr_dec |
( |
.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 |
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 ; |
|
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} ; |
|
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 pcim_if_err_pending_in = wbu_err_pending_in ; |
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_werror_in = pcim_sm_werror_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_pending_in (pcim_if_err_pending_in), |
.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_tabort_out), |
.tabort_received_out (pcim_if_mabort_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), |
.werror_in (pcim_if_werror_in), |
.rerror_in (pcim_if_rerror_in), |
.first_in (pcim_if_first_in), |
.mabort_in (pcim_if_mabort_in) |
); |
|
// 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), |
.load_next_out (pcim_sm_load_next_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), |
.werror_out (pcim_sm_werror_out), |
.rerror_out (pcim_sm_rerror_out), |
.first_out (pcim_sm_first_out), |
.mabort_out (pcim_sm_mabort_out) |
) ; |
|
endmodule |
/verilog/wb_slave.v
0,0 → 1,966
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`include "bus_commands.v" |
`include "constants.v" |
`include "timescale.v" |
|
module 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, |
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 - when error reporting is enabled and PCI master detects an error while completing |
posted write on PCI, then WISHBONE slave unit doesn't accept any new requests or posted writes. Delayed completions |
are allowed to complete on WISHBONE if all other requirements are satisfied also. |
---------------------------------------------------------------------------------------------------------------------*/ |
input wbs_lock_in ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
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 |
|
reg [(`FSM_BITS - 1):0] c_state ; //current state register |
// synopsys state_vector c_state |
|
reg [(`FSM_BITS - 1):0] n_state ; //next state input to current state register |
|
// lock register - lock signal can cross clock domains, so here is register for it |
reg lock ; |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
lock <= #`FF_DELAY 1'b0 ; |
else |
lock <= #`FF_DELAY wbs_lock_in ; |
end |
|
// 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 |
|
|
// write operation indicator for delayed transaction requests |
assign del_write_out = WE_I ; |
|
// 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, lock } ; |
reg decode_en ; |
reg img_wallow ; |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
img_wallow <= #`FF_DELAY 1'b0 ; |
else |
if (decode_en) |
img_wallow <= #`FF_DELAY wimg_wallow ; |
end |
|
|
/*=================================================================================================================================================================================== |
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, lock } ; |
reg do_del_request ; |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
do_del_request <= #`FF_DELAY 1'b0 ; |
else |
if (decode_en) |
do_del_request <= #`FF_DELAY wdo_del_request ; |
end |
|
/*=================================================================================================================================================================================== |
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 active |
===================================================================================================================================================================================*/ |
wire del_bc_hit = ( del_bc == del_bc_in ) ; |
|
wire wdel_addr_hit = ( wb_del_addr_in == wb_addr_in ) && ( SEL_I == wb_del_be_in ) ; |
reg del_addr_hit ; |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
del_addr_hit <= #`FF_DELAY 1'b0 ; |
else |
if ( decode_en ) |
del_addr_hit <= #`FF_DELAY wdel_addr_hit ; |
end |
|
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 ; |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
del_completion_allow <= #`FF_DELAY 1'b0 ; |
else |
if ( decode_en ) |
del_completion_allow <= #`FF_DELAY wdel_completion_allow ; |
end |
|
wire do_dread_completion = del_completion_allow && del_bc_hit && 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 ; |
|
`else |
`ifdef HOST |
// only host implementation has access for generating interrupt acknowledge and configuration cycles |
// configuration cycle data register hit |
wire wccyc_hit = (wb_addr_in[8:2] == {1'b1, `CNF_DATA_ADDR}) && alligned_address ; |
reg ccyc_hit ; |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
ccyc_hit <= #`FF_DELAY 1'b0 ; |
else |
if (decode_en) |
ccyc_hit <= #`FF_DELAY wccyc_hit ; |
end |
|
wire wiack_hit = (wb_addr_in[8:2] == {1'b1, `INT_ACK_ADDR}) && alligned_address ; |
reg iack_hit ; |
|
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
iack_hit <= #`FF_DELAY 1'b0 ; |
else |
if (decode_en) |
iack_hit <= #`FF_DELAY wiack_hit ; |
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 && del_bc_hit && ccyc_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 && del_bc_hit && ccyc_hit; |
|
// variables for configuration access control signals |
reg conf_wenable ; |
assign wb_conf_wenable_out = conf_wenable ; |
|
`endif |
`endif |
|
// configuration read enable - supplied for host and guest bridges |
reg conf_renable ; |
assign wb_conf_renable_out = conf_renable ; |
|
// wire for write attempt - 1 when external WB master is attempting a write |
wire wattempt = ( CYC_I && STB_I && WE_I ) ; // write is qualified when cycle, strobe and write enable inputs are all high |
|
// wire for read attempt - 1 when external WB master is attempting a read |
wire rattempt = ( CYC_I && STB_I && ~WE_I ) ; // read is qualified when cycle and strobe are high and write enable is low |
|
// burst access indicator |
wire burst_transfer = CYC_I && CAB_I ; |
|
// SEL_I error indicator for IO and configuration 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 ; |
assign wbw_fifo_control_out = wbw_fifo_control ; //control bus output for WBW_FIFO |
|
// WBW_FIFO wenable output assignment |
reg wbw_fifo_wenable ; |
assign wbw_fifo_wenable_out = wbw_fifo_wenable ; //write enable for WBW_FIFO |
|
// WBR_FIFO control outputs |
reg wbr_fifo_flush, wbr_fifo_renable ; // flush and read enable outputs |
assign wbr_fifo_renable_out = wbr_fifo_renable ; //read enable for wbr_fifo |
|
reg wbr_fifo_flush_out ; |
|
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if ( reset_in ) |
wbr_fifo_flush_out <= #`FF_DELAY 1'b0 ; |
else |
wbr_fifo_flush_out <= #`FF_DELAY wbr_fifo_flush ; |
end |
|
// delayed transaction request control signals |
reg del_req, del_done ; |
assign del_req_out = del_req ; // read request |
assign del_done_out = del_done ; // read done |
|
// WISHBONE handshaking control outputs |
reg ack, rty, err ; |
assign ACK_O = ack ; |
assign RTY_O = rty ; |
assign ERR_O = err ; |
|
/*---------------------------------------------------------------------------------------------------------------------- |
Control logic for image hits |
img_hit - state of wb_hit_in bus when first data is acknowledged |
---------------------------------------------------------------------------------------------------------------------*/ |
reg [4:0] img_hit ; |
always@(posedge wb_clock_in or posedge reset_in) |
begin |
if (reset_in) |
img_hit <= #`FF_DELAY 5'h00 ; |
else |
if (decode_en) |
img_hit <= #`FF_DELAY wb_hit_in ; |
end |
|
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_pref_en_in & wb_hit_in) ; |
wire wmap = |(wb_map_in & wb_hit_in) ; |
|
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
begin |
pref_en <= #`FF_DELAY 1'b0 ; |
mrl_en <= #`FF_DELAY 1'b0 ; |
map <= #`FF_DELAY 1'b0 ; |
end |
else |
if ( decode_en ) |
begin |
pref_en <= #`FF_DELAY wpref_en ; |
mrl_en <= #`FF_DELAY wmrl_en ; |
map <= #`FF_DELAY wmap ; |
end |
end |
|
assign del_burst_out = CAB_I && pref_en && ~WE_I; // delayed burst indicator - only when WB master attempts CAB transfer and prefetch enable of corresponding image is set - |
// applies for reads only - delayed write cannot be a burst |
|
reg wb_conf_hit ; |
always@(posedge reset_in or posedge wb_clock_in) |
begin |
if (reset_in) |
wb_conf_hit <= #`FF_DELAY 1'b0 ; |
else |
if (decode_en) |
wb_conf_hit <= #`FF_DELAY wb_conf_hit_in ; |
end |
|
/*---------------------------------------------------------------------------------------------------------------------- |
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 |
---------------------------------------------------------------------------------------------------------------------*/ |
assign del_bc_out = del_bc ; |
|
always@(map or mrl_en or ccyc_hit or WE_I or wb_conf_hit or CAB_I or pref_en) |
begin |
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_IACK ; |
2'b00: del_bc = `BC_IACK ; |
endcase |
end |
else |
begin |
case ( {map, CAB_I && mrl_en && pref_en} ) |
2'b11: del_bc = `BC_IO_READ ; |
2'b10: del_bc = `BC_IO_READ ; |
2'b01: del_bc = `BC_MEM_READ_LN ; |
2'b00: del_bc = `BC_MEM_READ ; |
endcase |
end |
end |
|
// WISHBONE data output select lines for output multiplexor |
reg sdata_o_sel ; |
|
reg del_in_progress_out ; // 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 |
|
// 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 |
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 ; |
|
// WISHBONE data output selection - drive wbr output |
sdata_o_sel = WBR_SEL ; |
|
// read is not in progress |
del_in_progress_out = 1'b0 ; |
decode_en = 1'b0 ; |
wbw_data_out_sel = SEL_ADDR_IN ; |
|
case (c_state) |
S_IDLE: begin |
if ( wattempt || rattempt ) |
begin |
`ifdef WB_DECODE_FAST |
decode_en = 1'b1 ; |
n_state = S_START ; |
`else |
n_state = S_DEC1 ; |
`endif |
end |
else |
n_state = S_IDLE ; |
end |
|
S_DEC1: begin |
if ( wattempt || rattempt ) |
begin |
`ifdef WB_DECODE_MEDIUM |
decode_en = 1'b1 ; |
n_state = S_START ; |
`else |
n_state = S_DEC2 ; |
`endif |
end |
else |
n_state = S_IDLE ; |
end |
|
S_DEC2: begin |
|
if ( wattempt || rattempt ) |
begin |
decode_en = 1'b1 ; |
n_state = S_START ; |
end |
else |
n_state = S_IDLE ; |
end |
|
S_START:begin |
if (wb_conf_hit) // configuration space hit |
begin |
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 |
if(~(ccyc_hit || iack_hit)) |
sdata_o_sel = CONF_SEL ; |
end |
else |
n_state = S_IDLE ; // master terminated - go back to idle state |
|
end // wb_conf_hit*/ |
else |
if(wb_hit && (wattempt || rattempt)) |
begin |
|
// 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_out = 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 ; |
|
if ( ~burst_transfer || wattempt && ( ~alligned_address || wbw_fifo_almost_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_out = 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 && ~(wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] || wbr_fifo_control_in[`LAST_CTRL_BIT]) ; |
end |
else |
begin |
n_state = S_READ ; |
end |
end // S_READ |
|
S_CONF_WRITE: begin |
`ifdef HOST |
wbw_data_out_sel = SEL_CCYC_ADDR ; |
`endif |
n_state = S_IDLE ; // next state after configuration access is always idle |
del_req = do_ccyc_req && ~burst_transfer ; |
del_done = do_ccyc_comp && ~burst_transfer ; |
del_in_progress_out = do_ccyc_comp && ~burst_transfer ; |
|
if ( burst_transfer || ~alligned_address ) |
begin |
err = 1'b1 ; |
end |
else |
begin |
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 |
end |
end // S_CONF_WRITE |
|
S_CONF_READ: begin |
`ifdef HOST |
wbw_data_out_sel = SEL_CCYC_ADDR ; |
`endif |
n_state = S_IDLE ; // next state after configuration access is always idle |
del_req = ~burst_transfer && ( do_ccyc_req || do_iack_req ); |
del_done = ~burst_transfer && ( do_ccyc_comp || do_iack_comp ) ; |
del_in_progress_out = ~burst_transfer && ( do_ccyc_comp || do_iack_comp ) ; |
wbr_fifo_renable = ~burst_transfer && ( do_ccyc_comp || do_iack_comp ) ; |
|
if ( ~(ccyc_hit || iack_hit) ) |
sdata_o_sel = CONF_SEL ; |
|
if ( burst_transfer || ~alligned_address ) |
begin |
err = 1'b1 ; |
end |
else |
begin |
|
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 |
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 |
|
// Configuration space byte enables output |
assign wb_conf_be_out = SEL_I ; // just route select lines from WISHBONE to conf space |
|
// data output assignment - for image writes, first data is address, subsequent data comes from intermediate register |
reg [31:0] wb_data_out ; |
`ifdef HOST |
always@(wbw_data_out_sel or wb_addr_in or ccyc_addr_in or d_incoming) |
begin |
case ( wbw_data_out_sel ) |
SEL_CCYC_ADDR: wb_data_out = ccyc_addr_in ; |
SEL_DATA_IN: wb_data_out = d_incoming ; |
default: wb_data_out = wb_addr_in ; |
endcase |
end |
`else |
`ifdef GUEST |
always@(wbw_data_out_sel or wb_addr_in or d_incoming) |
begin |
if ( wbw_data_out_sel ) |
wb_data_out = wb_addr_in ; |
else |
wb_data_out = 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 ; |
assign wb_cbe_out = wb_cbe ; |
|
always@(wbw_data_out_sel or d_incoming or map) |
begin |
if (wbw_data_out_sel && map) |
wb_cbe = `BC_IO_WRITE ; |
else |
if (wbw_data_out_sel) |
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 ; |
`else |
`ifdef HOST |
assign wb_conf_data_out = SDATA_I ; |
`endif |
`endif |
|
// WISHBONE data output multiplexor |
reg [31:0] sdata ; |
assign SDATA_O = sdata ; |
|
always@(sdata_o_sel or wbr_fifo_data_in or wb_conf_data_in) |
begin |
case (sdata_o_sel) |
WBR_SEL :sdata = wbr_fifo_data_in ; |
CONF_SEL:sdata = wb_conf_data_in ; |
endcase |
end |
|
endmodule //WB_SLAVE |
/verilog/wbw_fifo_control.v
0,0 → 1,404
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 "constants.v" |
`include "timescale.v" |
`ifdef FPGA |
// fifo design in FPGA will be synchronous |
`ifdef SYNCHRONOUS |
`else |
`define SYNCHRONOUS |
`endif |
`endif |
module WBW_FIFO_CONTROL |
( |
rclock_in, |
wclock_in, |
renable_in, |
wenable_in, |
reset_in, |
flush_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 ; |
|
// 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 |
// grey code pipeline for write address |
reg [(ADDR_LENGTH - 1):0] wgrey_addr ; // current |
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_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] ; |
|
// FFs for registered empty and full flags |
reg empty ; |
reg full ; |
|
// almost_full tag |
reg almost_full ; |
|
// write allow wire - writes are allowed when fifo is not full |
wire wallow = wenable_in && ~full ; |
|
// write allow output assignment |
assign wallow_out = wallow && ~full ; |
|
// read allow wire |
wire rallow ; |
|
// full output assignment |
assign full_out = full ; |
|
// almost full output assignment |
assign almost_full_out = almost_full && ~full ; |
|
// clear generation for FFs and registers |
wire clear = reset_in || flush_in ; |
|
`ifdef SYNCHRONOUS |
|
reg wclock_nempty_detect ; |
always@(posedge reset_in or posedge wclock_in) |
begin |
if (reset_in) |
wclock_nempty_detect <= #`FF_DELAY 1'b0 ; |
else |
wclock_nempty_detect <= #`FF_DELAY (rgrey_addr != wgrey_addr) ; |
end |
|
// special synchronizing mechanism for different implementations - in synchronous imp., empty is prolonged for 1 clock edge if no write clock comes after initial write |
reg stretched_empty ; |
always@(posedge rclock_in or posedge clear) |
begin |
if(clear) |
stretched_empty <= #`FF_DELAY 1'b1 ; |
else |
stretched_empty <= #`FF_DELAY empty && ~wclock_nempty_detect ; |
end |
|
// empty output is actual empty + 1 read clock cycle ( stretched empty ) |
assign empty_out = empty || stretched_empty ; |
|
//rallow generation |
assign rallow = renable_in && ~empty && ~stretched_empty ; // reads allowed if read enable is high and FIFO is not empty |
|
// rallow output assignment |
assign rallow_out = rallow ; |
|
// 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[(ADDR_LENGTH - 1):1] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0}} ; |
raddr_plus_one[0] <= #`FF_DELAY 1'b1 ; |
end |
else if (rallow) |
raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ; |
end |
|
// raddr is filled with raddr_plus_one on rising read clock edge when rallow is high |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
// initial value is 000......00 |
raddr <= #`FF_DELAY { ADDR_LENGTH{1'b0}} ; |
else if (rallow) |
raddr <= #`FF_DELAY raddr_plus_one ; |
end |
|
`else |
// asynchronous RAM storage for FIFOs - somewhat simpler control logic |
//rallow generation |
assign rallow = renable_in && ~empty ; |
|
assign rallow_out = rallow ; |
|
// read address counter - normal counter, nothing to it |
// for asynchronous implementation, there is no need for pointing to next address. |
// On clock edge that read is performed, read address will change and on the next clock edge |
// asynchronous memory will provide next data |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
// initial value is 000......00 |
raddr <= #`FF_DELAY { ADDR_LENGTH{1'b0}} ; |
else if (rallow) |
raddr <= #`FF_DELAY raddr + 1'b1 ; |
end |
|
assign empty_out = empty ; |
assign raddr_out = raddr ; |
`endif |
|
/*----------------------------------------------------------------------------------------------- |
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 code register for two before read address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......010 |
rgrey_minus2[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_minus2[(ADDR_LENGTH - 2):2] <= #`FF_DELAY { (ADDR_LENGTH - 3){1'b0} } ; |
rgrey_minus2[1:0] <= #`FF_DELAY 2'b10 ; |
end |
else |
if (rallow) |
rgrey_minus2 <= #`FF_DELAY rgrey_minus1 ; |
end |
|
// grey code register for one before read address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......011 |
rgrey_minus1[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_minus1[(ADDR_LENGTH - 2):2] <= #`FF_DELAY { (ADDR_LENGTH - 3){1'b0} } ; |
rgrey_minus1[1:0] <= #`FF_DELAY 2'b11 ; |
end |
else |
if (rallow) |
rgrey_minus1 <= #`FF_DELAY rgrey_addr ; |
end |
|
// grey code register for read address - represents current Read Address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100.......01 |
rgrey_addr[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_addr[(ADDR_LENGTH - 2):1] <= #`FF_DELAY { (ADDR_LENGTH - 2){1'b0} } ; |
rgrey_addr[0] <= #`FF_DELAY 1'b1 ; |
end |
else |
if (rallow) |
rgrey_addr <= #`FF_DELAY rgrey_next ; |
end |
|
// grey code register for next read address - represents Grey Code of next read address |
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......00 |
rgrey_next[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
rgrey_next[(ADDR_LENGTH - 2):0] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0} } ; |
end |
else |
if (rallow) |
rgrey_next <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ; |
end |
|
/*-------------------------------------------------------------------------------------------- |
Write address control consists of write address counter and two Grey Code Registers: |
- wgrey_addr represents current Grey Coded write address |
- wgrey_next represents Grey Coded next write address |
----------------------------------------------------------------------------------------------*/ |
// grey code register for write address |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100.....001 |
wgrey_addr[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
wgrey_addr[(ADDR_LENGTH - 2):1] <= #`FF_DELAY { (ADDR_LENGTH - 2){1'b0} } ; |
wgrey_addr[0] <= #`FF_DELAY 1'b1 ; |
end |
else |
if (wallow) |
wgrey_addr <= #`FF_DELAY wgrey_next ; |
end |
|
// grey code register for next write address |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
begin |
// initial value is 100......00 |
wgrey_next[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ; |
wgrey_next[(ADDR_LENGTH - 2):0] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0} } ; |
end |
else |
if (wallow) |
wgrey_next <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ; |
end |
|
// write address counter - nothing special |
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
// initial value 00.........00 |
waddr <= #`FF_DELAY { (ADDR_LENGTH){1'b0} } ; |
else |
if (wallow) |
waddr <= #`FF_DELAY waddr + 1'b1 ; |
end |
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Registered full control: |
registered full is set on rising edge of wclock_in when there is one free location in and another written to fifo |
It's kept high until something is read from FIFO, which is registered on |
next rising write clock edge. |
|
Registered almost full control: |
Almost full flag is set on rising wclock_in edge when there are two unused locations left in and another written to fifo. |
It is set until something is read/written from/to fifo |
--------------------------------------------------------------------------------------------------------------------------------*/ |
//combinatorial input to Registered full FlipFlop |
wire reg_full = wallow && (wgrey_next == rgrey_minus1) || (wgrey_next == rgrey_addr) ; |
|
always@(posedge wclock_in or posedge clear) |
begin |
if (clear) |
full <= #`FF_DELAY 1'b0 ; |
else |
full <= #`FF_DELAY reg_full ; |
end |
|
// input for almost full latch |
wire reg_almost_full_in = wallow && (wgrey_next == rgrey_minus2) || (wgrey_next == rgrey_minus1) ; |
|
always@(posedge clear or posedge wclock_in) |
begin |
if (clear) |
almost_full <= #`FF_DELAY 1'b0 ; |
else |
almost_full <= #`FF_DELAY reg_almost_full_in ; |
end |
|
/*------------------------------------------------------------------------------------------------------------------------------ |
Registered empty control: |
registered empty is set on rising edge of rclock_in when one location is used and read from fifo. It's kept high |
until something is written to the fifo, which is registered on the next clock edge. |
|
Registered almost empty control: |
Almost empty is set on rising edge of rclock_in when two locations are used and one read. It's kept set until something |
is read/written from/to fifo. |
--------------------------------------------------------------------------------------------------------------------------------*/ |
// combinatorial input for registered emty FlipFlop |
wire comb_almost_empty = (rgrey_next == wgrey_addr) ; |
wire comb_empty = (rgrey_addr == wgrey_addr) ; |
wire reg_empty = renable_in && comb_almost_empty || comb_empty ; |
|
always@(posedge rclock_in or posedge clear) |
begin |
if (clear) |
empty <= #`FF_DELAY 1'b1 ; |
else |
empty <= #`FF_DELAY reg_empty ; |
end |
|
endmodule |
/verilog/par_crit.v
0,0 → 1,75
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
`include "timescale.v" |
|
module 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/out_reg.v
0,0 → 1,100
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:46 mihad |
// New project directory structure |
// |
// |
|
`include "constants.v" |
`include "timescale.v" |
|
// 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 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 ; |
|
wire en_n = ~en_in ; |
|
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 ) |
en_out <= #`FF_DELAY 1'b1 ; |
else if ( en_en_in ) |
en_out <= #`FF_DELAY en_n ; |
end |
|
endmodule |
/verilog/pci_target32_interface.v
0,0 → 1,1142
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.1.1.1 2001/10/02 15:33:47 mihad |
// New project directory structure |
// |
// |
|
`include "bus_commands.v" |
`include "constants.v" |
`include "timescale.v" |
|
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, |
req_in, |
rdy_in, |
addr_phase_in, |
bckp_trdy_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, |
pciw_fifo_full_out, |
pcir_fifo_data_err_out, |
wbw_fifo_empty_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_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_two_left_in, |
pciw_fifo_almost_full_in, |
pciw_fifo_full_in, |
wbw_fifo_empty_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 |
// 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_trdy_in ; // TRDY output (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 with OR without 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 |
|
|
/*================================================================================================================== |
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_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 |
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_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 |
|
|
/*================================================================================================================== |
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 |
wire hit0_in ; |
wire [31:0] address0_in ; |
wire hit1_in ; |
wire [31:0] address1_in ; |
`ifdef PCI_IMAGE2 |
wire hit2_in ; |
wire [31:0] address2_in ; |
`endif |
`ifdef PCI_IMAGE3 |
wire hit2_in ; |
wire [31:0] address2_in ; |
wire hit3_in ; |
wire [31:0] address3_in ; |
`endif |
`ifdef PCI_IMAGE4 |
wire hit2_in ; |
wire [31:0] address2_in ; |
wire hit3_in ; |
wire [31:0] address3_in ; |
wire hit4_in ; |
wire [31:0] address4_in ; |
`endif |
`ifdef PCI_IMAGE5 |
wire hit2_in ; |
wire [31:0] address2_in ; |
wire hit3_in ; |
wire [31:0] address3_in ; |
wire hit4_in ; |
wire [31:0] address4_in ; |
wire hit5_in ; |
wire [31:0] address5_in ; |
`endif |
`ifdef PCI_IMAGE6 |
wire hit2_in ; |
wire [31:0] address2_in ; |
wire hit3_in ; |
wire [31:0] address3_in ; |
wire hit4_in ; |
wire [31:0] address4_in ; |
wire hit5_in ; |
wire [31:0] address5_in ; |
`endif |
|
// Include address decoders |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder0 |
(.hit (hit0_in), |
.addr_out (address0_in), |
.addr_in (address_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) |
) ; |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder1 |
(.hit (hit1_in), |
.addr_out (address1_in), |
.addr_in (address_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_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder2 |
(.hit (hit2_in), |
.addr_out (address2_in), |
.addr_in (address_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_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder2 |
(.hit (hit2_in), |
.addr_out (address2_in), |
.addr_in (address_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) |
) ; |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder3 |
(.hit (hit3_in), |
.addr_out (address3_in), |
.addr_in (address_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_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder2 |
(.hit (hit2_in), |
.addr_out (address2_in), |
.addr_in (address_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) |
) ; |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder3 |
(.hit (hit3_in), |
.addr_out (address3_in), |
.addr_in (address_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) |
) ; |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder4 |
(.hit (hit4_in), |
.addr_out (address4_in), |
.addr_in (address_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_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder2 |
(.hit (hit2_in), |
.addr_out (address2_in), |
.addr_in (address_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) |
) ; |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder3 |
(.hit (hit3_in), |
.addr_out (address3_in), |
.addr_in (address_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) |
) ; |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder4 |
(.hit (hit4_in), |
.addr_out (address4_in), |
.addr_in (address_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) |
) ; |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder5 |
(.hit (hit5_in), |
.addr_out (address5_in), |
.addr_in (address_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 |
`ifdef PCI_IMAGE6 |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder2 |
(.hit (hit2_in), |
.addr_out (address2_in), |
.addr_in (address_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) |
) ; |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder3 |
(.hit (hit3_in), |
.addr_out (address3_in), |
.addr_in (address_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) |
) ; |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder4 |
(.hit (hit4_in), |
.addr_out (address4_in), |
.addr_in (address_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) |
) ; |
PCI_DECODER #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder5 |
(.hit (hit5_in), |
.addr_out (address5_in), |
.addr_in (address_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 PCI_IMAGE6 |
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 |
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 |
`ifdef PCI_IMAGE6 |
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_in or |
pre_fetch_en4_in or |
pre_fetch_en3_in or |
pre_fetch_en2_in or |
pre_fetch_en1_in or |
pre_fetch_en0_in |
) |
begin |
addr_claim <= (hit5_in || hit4_in || hit3_in || hit2_in) || (hit1_in || hit0_in) ; |
case ({hit5_in, hit4_in, hit3_in, hit2_in, hit1_in, hit0_in}) |
6'b010000 : |
begin |
address <= address4_in ; |
pre_fetch_en <= pre_fetch_en4_in ; |
end |
6'b001000 : |
begin |
address <= address3_in ; |
pre_fetch_en <= pre_fetch_en3_in ; |
end |
6'b000100 : |
begin |
address <= address2_in ; |
pre_fetch_en <= pre_fetch_en2_in ; |
end |
6'b000010 : |
begin |
address <= address1_in ; |
pre_fetch_en <= pre_fetch_en1_in ; |
end |
6'b000001 : |
begin |
address <= address0_in ; |
pre_fetch_en <= pre_fetch_en0_in ; |
end |
default : |
begin |
address <= address5_in ; |
pre_fetch_en <= pre_fetch_en5_in ; |
end |
endcase |
end |
`else |
`ifdef PCI_IMAGE5 |
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_in or |
pre_fetch_en4_in or |
pre_fetch_en3_in or |
pre_fetch_en2_in or |
pre_fetch_en1_in or |
pre_fetch_en0_in |
) |
begin |
addr_claim <= (hit5_in || hit4_in || hit3_in || hit2_in) || (hit1_in || hit0_in) ; |
case ({hit5_in, hit4_in, hit3_in, hit2_in, hit1_in, hit0_in}) |
6'b010000 : |
begin |
address <= address4_in ; |
pre_fetch_en <= pre_fetch_en4_in ; |
end |
6'b001000 : |
begin |
address <= address3_in ; |
pre_fetch_en <= pre_fetch_en3_in ; |
end |
6'b000100 : |
begin |
address <= address2_in ; |
pre_fetch_en <= pre_fetch_en2_in ; |
end |
6'b000010 : |
begin |
address <= address1_in ; |
pre_fetch_en <= pre_fetch_en1_in ; |
end |
6'b000001 : |
begin |
address <= address0_in ; |
pre_fetch_en <= pre_fetch_en0_in ; |
end |
default : |
begin |
address <= address5_in ; |
pre_fetch_en <= pre_fetch_en5_in ; |
end |
endcase |
end |
`else |
`ifdef PCI_IMAGE4 |
always@(hit4_in or hit3_in or hit2_in or hit1_in or hit0_in or |
address4_in or address3_in or address2_in or address1_in or address0_in or |
pre_fetch_en4_in or |
pre_fetch_en3_in or |
pre_fetch_en2_in or |
pre_fetch_en1_in or |
pre_fetch_en0_in |
) |
begin |
addr_claim <= hit4_in || (hit3_in || hit2_in || hit1_in || hit0_in) ; |
case ({hit4_in, hit3_in, hit2_in, hit1_in, hit0_in}) |
5'b01000 : |
begin |
address <= address3_in ; |
pre_fetch_en <= pre_fetch_en3_in ; |
end |
5'b00100 : |
begin |
address <= address2_in ; |
pre_fetch_en <= pre_fetch_en2_in ; |
end |
5'b00010 : |
begin |
address <= address1_in ; |
pre_fetch_en <= pre_fetch_en1_in ; |
end |
5'b00001 : |
begin |
address <= address0_in ; |
pre_fetch_en <= pre_fetch_en0_in ; |
end |
default : |
begin |
address <= address4_in ; |
pre_fetch_en <= pre_fetch_en4_in ; |
end |
endcase |
end |
`else |
`ifdef PCI_IMAGE3 |
always@(hit3_in or hit2_in or hit1_in or hit0_in or |
address3_in or address2_in or address1_in or address0_in or |
pre_fetch_en3_in or |
pre_fetch_en2_in or |
pre_fetch_en1_in or |
pre_fetch_en0_in |
) |
begin |
addr_claim <= (hit3_in || hit2_in || hit1_in || hit0_in) ; |
case ({hit3_in, hit2_in, hit1_in, hit0_in}) |
4'b0100 : |
begin |
address <= address2_in ; |
pre_fetch_en <= pre_fetch_en2_in ; |
end |
4'b0010 : |
begin |
address <= address1_in ; |
pre_fetch_en <= pre_fetch_en1_in ; |
end |
4'b0001 : |
begin |
address <= address0_in ; |
pre_fetch_en <= pre_fetch_en0_in ; |
end |
default : |
begin |
address <= address3_in ; |
pre_fetch_en <= pre_fetch_en3_in ; |
end |
endcase |
end |
`else |
`ifdef PCI_IMAGE2 |
always@(hit2_in or hit1_in or hit0_in or |
address2_in or address1_in or address0_in or |
pre_fetch_en2_in or |
pre_fetch_en1_in or |
pre_fetch_en0_in |
) |
begin |
addr_claim <= (hit2_in || hit1_in || hit0_in) ; |
case ({hit2_in, hit1_in, hit0_in}) |
3'b010 : |
begin |
address <= address1_in ; |
pre_fetch_en <= pre_fetch_en1_in ; |
end |
3'b001 : |
begin |
address <= address0_in ; |
pre_fetch_en <= pre_fetch_en0_in ; |
end |
default : |
begin |
address <= address2_in ; |
pre_fetch_en <= pre_fetch_en2_in ; |
end |
endcase |
end |
`else |
always@(hit1_in or hit0_in or |
address1_in or address0_in or |
pre_fetch_en1_in or |
pre_fetch_en0_in |
) |
begin |
addr_claim <= (hit1_in || hit0_in) ; |
case ({hit1_in, hit0_in}) |
2'b01 : |
begin |
address <= address0_in ; |
pre_fetch_en <= pre_fetch_en0_in ; |
end |
default : |
begin |
address <= address1_in ; |
pre_fetch_en <= pre_fetch_en1_in ; |
end |
endcase |
end |
`endif |
`endif |
`endif |
`endif |
`endif |
|
// Address claim output to PCI Target SM |
assign addr_claim_out = addr_claim ; |
|
reg [11:0] strd_address ; // stored INPUT address for accessing Configuration space registers |
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 bckp_trdy_reg ; // delayed registered TRDY output equivalent signal |
reg trdy_asserted_reg ; // delayed bckp_trdy_reg signal |
|
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
strd_address <= 12'h000 ; |
norm_address <= 32'h0000_0000 ; |
norm_prf_en <= 1'b0 ; |
norm_bc <= 4'h0 ; |
same_read_reg <= 1'b0 ; |
end |
else |
begin |
if (addr_phase_in) |
begin |
strd_address <= address_in[11:0] ; |
norm_address <= address ; |
norm_prf_en <= pre_fetch_en ; |
norm_bc <= bc_in ; |
same_read_reg <= same_read_out ; |
end |
end |
end |
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
bckp_trdy_reg <= 1'b0 ; |
trdy_asserted_reg <= 1'b0 ; |
end |
else |
begin |
bckp_trdy_reg <= bckp_trdy_in ; |
trdy_asserted_reg <= bckp_trdy_reg ; |
end |
end |
// Signal indicates when target ready is deaserted on PCI bus |
wire trdy_asserted = trdy_asserted_reg && bckp_trdy_reg ; |
|
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 ; |
reg conf_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 |
conf_be_ok <= 1'b0 ; |
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]) ; |
conf_be_ok <= 1'b0 ; |
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]) ; |
conf_be_ok <= 1'b0 ; |
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]) ; |
conf_be_ok <= 1'b1 ; |
end |
endcase |
end |
|
reg calc_target_abort ; |
// Target abort indication regarding the registered bus command and current signals for byte enable checking |
always@(bc_in or hit0_in or io_be_ok or conf_be_ok) |
begin |
case (bc_in) |
// READ COMMANDS |
`BC_IO_READ : |
begin |
case ({hit0_in, hit0_conf}) |
2'b11 : |
begin |
calc_target_abort <= 1'b1 ; |
end |
default : |
begin |
if (io_be_ok) |
begin |
calc_target_abort <= 1'b0 ; |
end |
else |
begin |
calc_target_abort <= 1'b1 ; |
end |
end |
endcase |
end |
`BC_MEM_READ : |
begin |
case ({hit0_in, hit0_conf}) |
2'b11 : |
begin |
calc_target_abort <= 1'b0 ; |
end |
default : |
begin |
calc_target_abort <= 1'b0 ; |
end |
endcase |
end |
`BC_CONF_READ : |
begin |
case (conf_be_ok) |
1'b1 : |
begin |
calc_target_abort <= 1'b0 ; |
end |
default : |
begin |
calc_target_abort <= 1'b1 ; |
end |
endcase |
end |
`BC_MEM_READ_LN, |
`BC_MEM_READ_MUL : |
begin |
case ({hit0_in, hit0_conf}) |
2'b11 : |
begin |
calc_target_abort <= 1'b1 ; |
end |
default : |
begin |
calc_target_abort <= 1'b0 ; |
end |
endcase |
end |
// WRITE COMMANDS |
`BC_IO_WRITE : |
begin |
case ({hit0_in, hit0_conf}) |
2'b11 : |
begin |
calc_target_abort <= 1'b1 ; |
end |
default : |
begin |
if (io_be_ok) |
begin |
calc_target_abort <= 1'b0 ; |
end |
else |
begin |
calc_target_abort <= 1'b1 ; |
end |
end |
endcase |
end |
`BC_MEM_WRITE : |
begin |
case ({hit0_in, hit0_conf}) |
2'b11 : |
begin |
calc_target_abort <= 1'b0 ; |
end |
default : |
begin |
calc_target_abort <= 1'b0 ; |
end |
endcase |
end |
`BC_CONF_WRITE : |
begin |
case (conf_be_ok) |
1'b1 : |
begin |
calc_target_abort <= 1'b0 ; |
end |
default : |
begin |
calc_target_abort <= 1'b1 ; |
end |
endcase |
end |
`BC_MEM_WRITE_INVAL : |
begin |
case ({hit0_in, hit0_conf}) |
2'b11 : |
begin |
calc_target_abort <= 1'b1 ; |
end |
default : |
begin |
calc_target_abort <= 1'b0 ; |
end |
endcase |
end |
default : |
begin |
calc_target_abort <= 1'b0 ; |
end |
endcase |
end |
|
// 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 <= 32'h0000_0000 ; |
pcir_fifo_ctrl_reg <= 4'h0 ; |
end |
else |
begin |
if (load_medium_reg_in) |
begin |
pcir_fifo_data_reg <= pcir_fifo_data_in ; |
pcir_fifo_ctrl_reg <= pcir_fifo_control_in ; |
end |
end |
end |
|
// selecting "fifo data" from medium registers or from PCIR_FIFO |
wire [31:0] pcir_fifo_data = sel_fifo_mreg_in ? pcir_fifo_data_in : pcir_fifo_data_reg ; |
wire [3:0] pcir_fifo_ctrl = sel_fifo_mreg_in ? pcir_fifo_control_in : pcir_fifo_ctrl_reg ; |
|
// signal assignments to PCI Target FSM |
assign norm_access_to_config_out = (hit0_in && hit0_conf) ; |
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 |
assign disconect_wo_data_out = ( |
((pcir_fifo_ctrl[`LAST_CTRL_BIT] || pcir_fifo_empty_in || ~addr_burst_ok) && ~bc0_in && ~frame_reg_in) || |
((pciw_fifo_full_in || pciw_fifo_almost_full_in || pciw_fifo_two_left_in || ~addr_burst_ok) && bc0_in && ~frame_reg_in) |
) ; |
assign target_abort_out = (addr_phase_in && calc_target_abort) ; |
|
// control signal assignments to read request sinchronization module |
assign done_out = (~sel_conf_fifo_in && same_read_reg && ~trdy_asserted && 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 && same_read_reg && ~trdy_asserted && last_reg_in && ~pcir_fifo_empty_in) ; |
// flush signal for PCIR_FIFO must be registered, since it asinchronously resets some status registers |
reg pcir_fifo_flush_reg ; |
always@(posedge clk_in or posedge reset_in) |
begin |
if (reset_in) |
begin |
pcir_fifo_flush_reg <= 1'b0 ; |
end |
else |
begin |
pcir_fifo_flush_reg <= comp_flush_in || pcir_fifo_flush ; |
end |
end |
|
// signal assignments from fifo to PCI Target FSM |
assign wbw_fifo_empty_out = wbw_fifo_empty_in ; |
assign pciw_fifo_full_out = (pciw_fifo_full_in || pciw_fifo_almost_full_in || pciw_fifo_two_left_in) ; |
assign pcir_fifo_data_err_out = pcir_fifo_ctrl[`DATA_ERROR_CTRL_BIT] ; |
// signal assignments to fifo |
assign pcir_fifo_flush_out = pcir_fifo_flush_reg ; |
assign pcir_fifo_renable_out = fetch_pcir_fifo_in ; |
assign pciw_fifo_wenable_out = load_to_pciw_fifo_in ; |
assign pciw_fifo_control_out[`ADDR_CTRL_BIT] = 1'b0 ; |
assign pciw_fifo_control_out[`BURST_BIT] = rdy_in ? 1'b0 : ~frame_reg_in ; |
assign pciw_fifo_control_out[`DATA_ERROR_CTRL_BIT] = 1'b0 ; |
assign pciw_fifo_control_out[`LAST_CTRL_BIT] = rdy_in ? (last_reg_in || pciw_fifo_almost_full_in) : 1'b0 ; |
|
// data and address outputs assignments to PCI Target FSM |
assign data_out = sel_conf_fifo_in ? conf_data_in : pcir_fifo_data ; |
// data and address outputs assignments to read request sinchronization module |
assign req_out = req_in ; |
assign addr_out = norm_address ; |
assign be_out = be_in ; |
assign we_out = 1'b0 ; |
assign bc_out = norm_bc ; |
assign burst_out = ~frame_reg_in && norm_prf_en ; |
// data and address outputs assignments to PCIW_FIFO |
assign pciw_fifo_addr_data_out = rdy_in ? data_in : norm_address ; |
assign pciw_fifo_cbe_out = rdy_in ? be_in : norm_bc ; |
// data and address outputs assignments to Configuration space |
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 ; |
assign conf_re_out = fetch_conf_in ; |
|
|
endmodule |
/verilog/timescale.v
0,0 → 1,13
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "timescale.v" //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// |
|
// timescale directive is included in all core's modules for simulation purposes |
`timescale 1ns/10ps |
/verilog/pci_target32_trdy_crit.v
0,0 → 1,79
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 |
|
`include "constants.v" |
`include "timescale.v" |
|
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 |