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

Subversion Repositories theia_gpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /theia_gpu/branches/beta_1.1/rtl/IO
    from Rev 35 to Rev 58
    Reverse comparison

Rev 35 → Rev 58

/Module_MEM2WBM.v
0,0 → 1,112
`timescale 1ns / 1ps
`include "aDefinitions.v"
 
/**********************************************************************************
Theia, Ray Cast Programable graphic Processing Unit.
Copyright (C) 2010 Diego Valverde (diego.valverde.g@gmail.com)
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program 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 General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
***********************************************************************************/
/*
This unit is used when the External Address that comes into IO is not a immediate value,
ie. it is a value that we need to read from one of our internal memory locations.
Since each internal memory locations contains 3 * 32bits slots, ie X,Y and Z parts of the
memory location, then we make three requests for external data, one for every X Y and Z
part of our internal registry.So, summarising, each internal memory location, stores 3
external memory addresses to request to WBM. Once the 3 data has been read from outside world,
they will get stored back into 3 consecutive inernal memory addreses starting from
iDataInitialStorageAddress
*/
//---------------------------------------------------------------------
module MEM2WBMUnitB
(
input wire Clock,
input wire Reset,
input wire iEnable,
//output reg oSetAddress,
input wire[`DATA_ADDRESS_WIDTH-1:0] iMEMDataPointer,
input wire[`DATA_ADDRESS_WIDTH-1:0] iMEMDataPointer2,
output wire [`WIDTH-1:0] oReadDataElement,
output wire [`WIDTH-1:0] oReadDataElement2,
output wire[`DATA_ADDRESS_WIDTH-1:0] oDataReadAddress, //This tells MEM unit from wich address we want to read
output wire[`DATA_ADDRESS_WIDTH-1:0] oDataReadAddress2, //This tells MEM unit from wich address we want to read
input wire [`DATA_ROW_WIDTH-1:0] iReadDataBus, //This comes from the MEM unit
input wire [`DATA_ROW_WIDTH-1:0] iReadDataBus2, //This comes from the MEM unit
output wire oDataWriteEnable,
output wire oDataWriteEnable2,
output wire oDataAvailable,
input wire iRequestNextElement,
input wire[`DATA_ADDRESS_WIDTH-1:0] iDataInitialStorageAddress, //Initial address to store data ////########
output wire[`DATA_ADDRESS_WIDTH-1:0] oDataWriteAddress, //Were to store the values comming from WBM ////########
output wire oDone
);
assign oDataWriteEnable2 = 0;
assign oDataWriteEnable = 0; //We only read.
wire [3:0] wXYZSelector;
wire[`WIDTH-1:0] wValueFromBus,wLatchedValue;
assign oDataReadAddress = iMEMDataPointer;
assign oDataReadAddress2 = iMEMDataPointer2;
assign oDone = wXYZSelector[3];
 
wire wLacthNow;
assign oDataAvailable = iEnable & ~iRequestNextElement & wLacthNow & ~oDone;
 
FFD_POSEDGE_SYNCRONOUS_RESET # (1) FFD32_EnableDelay
(
.Clock( Clock ),
.Reset( Reset ),
.Enable( 1'b1 ),
.D( iEnable ),
.Q( wLacthNow )
);
 
assign oDataWriteAddress = iDataInitialStorageAddress;
 
 
SHIFTLEFT_POSEDGE #(4) SHL
(
.Clock(iRequestNextElement | ~iEnable),
.Enable(1'b1),
.Reset(~iEnable | Reset ),
.Initial(4'b1),
.O(wXYZSelector)
);
 
MUXFULLPARALELL_3SEL_WALKINGONE MUXA
(
.Sel( wXYZSelector ),
.I2( iReadDataBus[63:32]),
.I1( iReadDataBus[95:64]),
.I3( iReadDataBus[31:0] ),
.O1( oReadDataElement )
);
 
 
 
MUXFULLPARALELL_3SEL_WALKINGONE MUXA2
(
.Sel( wXYZSelector ),
.I2( iReadDataBus2[63:32]),
.I1( iReadDataBus2[95:64]),
.I3( iReadDataBus2[31:0] ),
.O1( oReadDataElement2 )
);
 
endmodule
//---------------------------------------------------------------------
/Module_WBM2MEM.v
0,0 → 1,152
 
`timescale 1ns / 1ps
`include "aDefinitions.v"
/**********************************************************************************
Theia, Ray Cast Programable graphic Processing Unit.
Copyright (C) 2010 Diego Valverde (diego.valverde.g@gmail.com)
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program 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 General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
***********************************************************************************/
/**
The Wish Bone bus has a 32 bit words.
However our internal bus is 96 bits (32 * 3) bits wide
for Data or 64 bits wide for Instructions (Hardvard Architecture).
If the iStore signal is one, WBM2MEMUnit provides a means to
store 2 or 3 incomming 32 bits frames into temporary Flip-Flops,
and then store the 96 or 64 bit value into a specified location
in the internal Instruction or Data Memory.
If the iStore signal is zero, WBMinputFifo passes the
32 bit value comming from the WB bus, directly through the oData
pin without storing it.
*/
 
module WBM2MEMUnit
(
input wire Clock,
input wire Reset,
input wire iEnable,
input wire iStore,
input wire[`DATA_ADDRESS_WIDTH-1:0] iAdr_DataWriteBack,
input wire iWBMDataAvailable,
input wire iWriteBack_Set,
//input wire[`WIDTH-1:0] iWBMInitialAddress,
//input wire iSetWBMInitialAddress,
input wire [`WIDTH-1:0] iWBMData, //Comes from WBM
output wire[`WIDTH-1:0] oData, //Goes back to geo
output wire oEnableWBM,
//output wire[`WIDTH-1:0] oAddressWBM,
output wire[`DATA_ADDRESS_WIDTH-1:0] oDataWriteAddress,
inout wire [`DATA_ROW_WIDTH-1:0] oDataBus,
output wire oDataWriteEnable,
output wire oDone
);
wire [`WIDTH-1:0] wVx;
wire [`WIDTH-1:0] wVy;
wire [`WIDTH-1:0] wVz;
wire wDelayAfterWriteEnable;
 
//assign oDataWriteAddress = iAdr_DataWriteBack;
 
wire CounterClock;
assign CounterClock = wDelayAfterWriteEnable | iWriteBack_Set;
 
UPCOUNTER_POSEDGE # (`DATA_ADDRESS_WIDTH) UP1
(
.Clock(Clock),
.Reset(iWriteBack_Set | Reset ),
.Enable(CounterClock),
.Initial(iAdr_DataWriteBack),
.Q(oDataWriteAddress)
);
 
 
wire[3:0] wSelXYZ;
//Every time WBM says is done, then shift the bit
//one position
 
CIRCULAR_SHIFTLEFT_POSEDGE # (4) SHL_A
(
.Clock( Clock ),
.Enable(iWBMDataAvailable),
.Reset(~iEnable | Reset ),
.Initial(4'b1),
.O(wSelXYZ)
);
 
 
FFD_POSEDGE_SYNCRONOUS_RESET # (`WIDTH) FFD32_WBMFIFO_Vx
(
.Clock( Clock ),
.Reset( ~iEnable | Reset ),
.Enable( wSelXYZ[0] & iWBMDataAvailable ),
.D( iWBMData ),
.Q( wVx )
);
 
//The data out is equal to the first vertex that has
//been captured
assign oData = wVx;
 
 
FFD_POSEDGE_SYNCRONOUS_RESET # (`WIDTH) FFD32_WBMFIFO_Vy
(
.Clock( Clock ),
.Reset( ~iEnable | Reset),
.Enable( wSelXYZ[1] & iWBMDataAvailable ),
.D( iWBMData ),
.Q( wVy )
);
 
FFD_POSEDGE_SYNCRONOUS_RESET # (`WIDTH) FFD32_WBMFIFO_Vz
(
.Clock( Clock ),
.Reset( ~iEnable | Reset ),
.Enable( wSelXYZ[2] & iWBMDataAvailable),
.D( iWBMData ),
.Q( wVz )
);
 
assign oDataBus = {wVx,wVy,wVz};
 
 
assign oDataWriteEnable = wSelXYZ[3];
assign oDone = (iStore) ? wSelXYZ[3] : wSelXYZ[1];
assign oEnableWBM = ~oDone;
 
FFD_POSEDGE_SYNCRONOUS_RESET # (`WIDTH) FFD32_WBMFIFO_V2
(
.Clock( Clock ),
.Reset( Reset ),
.Enable( 1'b1 ),
.D( wSelXYZ[3] ),
.Q(wDelayAfterWriteEnable )
);
 
/*
always @ (posedge iWBMDataAvailable)
begin
$display("%d Got something %h!",$time,iWBMData);
$display("%d Got wSelXYZ %b!",$time,wSelXYZ);
end
*/
endmodule
 
//----------------------------------------------------
/Module_WishBoneSlave.v
0,0 → 1,159
`timescale 1ns / 1ps
`include "aDefinitions.v"
 
 
 
`define TAG_INSTRUCTION_ADDRESS_TYPE 2'b10
`define TAG_DATA_ADDRESS_TYPE 2'b01
/**********************************************************************************
Theia, Ray Cast Programable graphic Processing Unit.
Copyright (C) 2010 Diego Valverde (diego.valverde.g@gmail.com)
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program 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 General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
***********************************************************************************/
//------------------------------------------------------------------------------
module WishBoneSlaveUnit
(
//WB Input signals
input wire CLK_I,
input wire RST_I,
input wire STB_I,
input wire WE_I,
input wire[`WB_WIDTH-1:0] DAT_I,
input wire[`WB_WIDTH-1:0] ADR_I,
input wire [1:0] TGA_I,
output wire ACK_O,
input wire MST_I, //Master In!
input wire CYC_I,
output wire[`DATA_ADDRESS_WIDTH-1:0] oDataWriteAddress,
output wire [`DATA_ROW_WIDTH-1:0] oDataBus,
output wire [`ROM_ADDRESS_WIDTH-1:0] oInstructionWriteAddress,
output wire [`INSTRUCTION_WIDTH-1:0] oInstructionBus,
output wire oDataWriteEnable,
output wire oInstructionWriteEnable
 
);
 
FFD_POSEDGE_SYNCRONOUS_RESET # (16) FFADR
(
.Clock( CYC_I ),
.Reset( RST_I ),
.Enable(1'b1),
.D( ADR_I[15:0] ),
.Q( oInstructionWriteAddress )
);
 
assign oDataWriteAddress = oInstructionWriteAddress;
 
wire[1:0] wTGA_Latched;
 
FFD_POSEDGE_SYNCRONOUS_RESET # (2) FFADDRTYPE
(
.Clock( CYC_I ),
.Reset( RST_I ),
.Enable(1'b1),
.D( TGA_I ),
.Q( wTGA_Latched )
);
 
 
 
wire Clock,Reset;
assign Clock = CLK_I;
assign Reset = RST_I;
 
 
wire wLatchNow;
assign wLatchNow = STB_I & WE_I;
 
//1 Clock cycle after we assert the latch signal
//then the FF has the data ready to propagate
wire wDelay;
FFD_POSEDGE_SYNCRONOUS_RESET # (1) FFOutputDelay
(
.Clock( Clock ),
.Enable( 1'b1 ),
.Reset( Reset ),
.D( wLatchNow ),
.Q( wDelay )
);
 
assign ACK_O = wDelay & STB_I; //make sure we set ACK_O back to zero when STB_I is zero
 
 
wire [2:0] wXYZSel;
 
SHIFTLEFT_POSEDGE #(3) SHL
(
.Clock(CLK_I),
.Enable(STB_I & ~ACK_O),
.Reset(~CYC_I),
.Initial(3'b1),
.O(wXYZSel)
);
 
 
//Flip Flop to Store Vx
wire [`WIDTH-1:0] wVx;
FFD_POSEDGE_SYNCRONOUS_RESET # (`WIDTH) FFD32_WBS2MEM_Vx
(
.Clock( Clock ),
.Reset( Reset ),
.Enable( wXYZSel[0] & STB_I ),
.D( DAT_I ),
.Q( wVx )
);
 
 
//Flip Flop to Store Vy
wire [`WIDTH-1:0] wVy;
FFD_POSEDGE_SYNCRONOUS_RESET # (`WIDTH) FFD32_WBS2MEM_Vy
(
.Clock( Clock ),
.Reset( Reset ),
.Enable( wXYZSel[1] & STB_I ),
.D( DAT_I ),
.Q( wVy )
);
 
//Flip Flop to Store Vz
wire [`WIDTH-1:0] wVz;
 
FFD_POSEDGE_SYNCRONOUS_RESET # (`WIDTH) FFD32_WBS2MEM_Vz
(
.Clock( Clock ),
.Reset( Reset ),
.Enable( wXYZSel[2] & STB_I ),
.D( DAT_I ),
.Q( wVz )
);
 
assign oDataBus = {wVx,wVy,wVz};
assign oInstructionBus = {wVx,wVy};
wire wIsInstructionAddress,wIsDataAddress;
assign wIsInstructionAddress = (wTGA_Latched == `TAG_INSTRUCTION_ADDRESS_TYPE) ? 1'b1 : 1'b0;
assign wIsDataAddress = (wTGA_Latched == `TAG_DATA_ADDRESS_TYPE ) ? 1'b1 : 1'b0;
 
assign oDataWriteEnable = (MST_I && !CYC_I && wIsInstructionAddress) ? 1'b1 : 1'b0;
assign oInstructionWriteEnable = ( MST_I && !CYC_I && wIsDataAddress) ? 1'b1 : 1'b0;
 
 
 
endmodule
//------------------------------------------------------------------------------
/Module_WishBoneMaster.v
0,0 → 1,109
`timescale 1ns / 1ps
`include "aDefinitions.v"
/**********************************************************************************
Theia, Ray Cast Programable graphic Processing Unit.
Copyright (C) 2010 Diego Valverde (diego.valverde.g@gmail.com)
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program 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 General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
***********************************************************************************/
/*
In order to read the geometry, we will behave as a master.
Performing single Reads Bus cycles should be sufficient.
Choosing 32 bit for bus width for simplicity.
*/
 
module WishBoneMasterUnit
(
//WB Input signals
input wire CLK_I,
input wire RST_I,
input wire ACK_I,
input wire [`WB_WIDTH-1:0 ] DAT_I,
output wire [`WB_WIDTH-1:0] DAT_O,
 
 
//WB Output Signals
output wire [`WB_WIDTH-1:0 ] ADR_O,
output wire WE_O,
output wire STB_O,
output wire CYC_O,
output wire [1:0] TGC_O,
 
//Signals from inside the GPU
input wire iEnable,
input wire iBusCyc_Type,
input wire [`WIDTH-1:0 ] iAddress,
input wire iAddress_Set,
output wire oDataReady,
input wire [`WIDTH-1:0 ] iData,
output wire [`WIDTH-1:0 ] oData
 
);
wire wReadOperation;
//assign ADR_O = iAddress;
assign wReadOperation = (iBusCyc_Type == `WB_SIMPLE_READ_CYCLE) ? 1 : 0;
assign WE_O = (iBusCyc_Type == `WB_SIMPLE_WRITE_CYCLE && iEnable) ? 1 : 0;
 
assign STB_O = iEnable & ~ACK_I;
assign CYC_O = iEnable;
 
assign DAT_O = (wReadOperation | ~iEnable ) ? `WB_WIDTH'bz : iData;
 
 
//The ADR_O, it increments with each ACK_I, and it resets
//to the value iAddress everytime iAddress_Set is 1.
UPCOUNTER_POSEDGE # (`WIDTH) WBM_O_ADDRESS
(
.Clock(CLK_I),
.Reset( iAddress_Set ),
.Enable(ACK_I | iAddress_Set),
.Initial(iAddress),
.Q(ADR_O)
);
 
 
 
FFD_POSEDGE_SYNCRONOUS_RESET # ( `WIDTH ) FFD1
(
.Clock(ACK_I),
.Reset(~iEnable),
.Enable(wReadOperation),
.D(DAT_I),
.Q(oData)
);
 
wire wDelayDataReady;
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD2
(
.Clock(CLK_I),
.Reset(~iEnable),
.Enable(wReadOperation),
.D(ACK_I),
.Q(wDelayDataReady)
);
/*
always @ (posedge wDelayDataReady)
begin
$display("WBM Got data: %h ",oData);
$display("oDataReady = %d",oDataReady );
end
*/
 
assign oDataReady = wDelayDataReady & iEnable;
 
endmodule
 
/Unit_IO.v
0,0 → 1,267
`timescale 1ns / 1ps
`include "aDefinitions.v"
`define ADR_IMM 1
`define ADR_POINTER 0
/**********************************************************************************
Theia, Ray Cast Programable graphic Processing Unit.
Copyright (C) 2010 Diego Valverde (diego.valverde.g@gmail.com)
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program 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 General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
***********************************************************************************/
//--------------------------------------------------------------------------
module IO_Unit
(
input wire Clock,
input wire Reset,
input wire iEnable,
input wire [`DATA_ADDRESS_WIDTH-1:0] iDat_O_Pointer, //Pointer to what we want to send via DAT_O
input wire [`WIDTH-1:0] iAdr_O_Imm, //Value to assign to ADR_O
input wire [`DATA_ADDRESS_WIDTH-1:0] iAdr_O_Pointer, //Pointer to value to assing to ADR_O
input wire iAdr_O_Type, //Should we use iAdr_O_Imm or iAdr_O_Pointer
input wire iAdr_O_Set, //Should we set
input wire iBusCyc_Type, //Bus cycle type: simple read/write, etc.
input wire iStore, //Should we store read data into MEM
input wire [`DATA_ROW_WIDTH-1:0] iReadDataBus, //MEM Data read bus 1
input wire [`DATA_ROW_WIDTH-1:0] iReadDataBus2, //MEM Data read bus 2
input wire[`DATA_ADDRESS_WIDTH-1:0] iAdr_DataWriteBack, //Where in MEM we want to store DAT_I
input wire iWriteBack_Set, //We want to set the Write back Address?
output wire[`DATA_ADDRESS_WIDTH-1:0] oDataReadAddress,
output wire[`DATA_ADDRESS_WIDTH-1:0] oDataReadAddress2,
output wire[`DATA_ADDRESS_WIDTH-1:0] oDataWriteAddress,
output wire oDataWriteEnable,
output wire [`DATA_ROW_WIDTH-1:0] oDataBus,
output wire [`INSTRUCTION_WIDTH-1:0] oInstructionBus,
output wire oInstructionWriteEnable,
output wire [`ROM_ADDRESS_WIDTH-1:0] oInstructionWriteAddress,
inout wire [`WIDTH-1:0] oData,
output wire oDone,
//Theia specific interfaces
input wire MST_I,
//Wish Bone Interfaces
output wire [31:0] DAT_O,
input wire [31:0] DAT_I,
input wire ACK_I,
output wire ACK_O,
output wire [31:0] ADR_O,
output wire [31:0] ADR_I,
output wire WE_O,
input wire WE_I,
output wire STB_O,
input wire STB_I,
output wire CYC_O,
input wire CYC_I,
input wire [1:0] TGA_I,
output wire [1:0] TGC_O
);
 
 
wire [`WIDTH-1:0] wMEMToWBM2__ReadDataElement;
wire [`WIDTH-1:0] wMEMToWBM2__ReadDataElement2;
wire wMEMToWBM_2__Enable;
wire wWBMToMEM2__Done;
wire wWBM_2_WBMToMEM_DataAvailable;
wire [`WIDTH-1:0] wWBM_2_WBMToMEM_Data;
wire [`WIDTH-1:0] wWBS_2__WBMToMEM_Frame;
wire wWBMToMEM_2_WBM_Enable;
wire [`WIDTH-1:0] wWBMToMEM_2_WBM_Address;
wire wWBMToMEM2__oDataWriteEnable;
wire wAddrerssSelector2_oDataWriteEnable;
wire [`DATA_ROW_WIDTH-1:0] wWBMToMEM2__oDataBus;
wire [`DATA_ROW_WIDTH-1:0] wWBSToMEM2__oDataBus;
wire wAddressSelector_2__SetAddress;
wire [`WIDTH-1:0] wMEMToWBM_2__Address;
wire wMEMToWBM_2__Done;
wire w2WBMToMEM__Enable;
wire w2WBMToMEM__SetAddress;
wire wWBS_2__WBSToMEM_FrameAvailable;
wire[`WIDTH-1:0] wWBS_2__WBMToMEM_Address;
wire wWBSToMEM2__oDataWriteEnable;
wire[`DATA_ADDRESS_WIDTH-1:0] wWBSToMEM2__oDataWriteAddress;
wire[`DATA_ADDRESS_WIDTH-1:0] wWBMToMEM2__oDataWriteAddress;
 
wire wReadOperation;
assign wReadOperation = (iBusCyc_Type == `WB_SIMPLE_WRITE_CYCLE) ? 0 : 1;
 
assign wMEMToWBM_2__Address = ( iAdr_O_Type == `ADR_IMM ) ? iAdr_O_Imm : wMEMToWBM2__ReadDataElement;
assign w2WBMToMEM__Enable = ( iAdr_O_Type == `ADR_IMM ) ? iEnable : wMEMToWBM_2__Enable;
//assign oDone = ( (iAdr_O_Type == `ADR_IMM) && !(iBusCyc_Type == `WB_SIMPLE_WRITE_CYCLE) )
//? wWBMToMEM2__Done : wMEMToWBM_2__Done;
 
//TODO: WHEN ADR_POINTER Then Done is not until we got the 3 values from X,Y,Z in iAdr_O_Pointer
assign oDone = (iBusCyc_Type == `WB_SIMPLE_WRITE_CYCLE || iAdr_O_Type == `ADR_POINTER ) ? wMEMToWBM_2__Done : wWBMToMEM2__Done;
 
assign oDataWriteEnable = (MST_I == 1'b1) ? wWBSToMEM2__oDataWriteEnable : (wWBMToMEM2__oDataWriteEnable);// ^ wAddrerssSelector2_oDataWriteEnable);
assign oDataWriteAddress = (MST_I == 1'b1) ? wWBSToMEM2__oDataWriteAddress : wWBMToMEM2__oDataWriteAddress;
assign oDataBus = (MST_I == 1'b1) ? wWBSToMEM2__oDataBus : wWBMToMEM2__oDataBus;
 
 
 
wire [`DATA_ADDRESS_WIDTH-1:0] wMEMToWBM2_WBMToMEM_RAMWriteAddr;
wire [`DATA_ADDRESS_WIDTH-1:0] w2WBMToMEM_MEMWriteAddress;
 
assign w2WBMToMEM_MEMWriteAddress = ( iAdr_O_Type == `ADR_IMM) ? iAdr_DataWriteBack : wMEMToWBM2_WBMToMEM_RAMWriteAddr;
 
wire w2MEMToWBM_BusOperationComplete;
assign w2MEMToWBM_BusOperationComplete = (iBusCyc_Type == `WB_SIMPLE_WRITE_CYCLE) ? ACK_I : wWBMToMEM2__Done;
 
 
wire [`DATA_ADDRESS_WIDTH-1:0] w2MEMToWBM_DataPointer;
assign w2MEMToWBM_DataPointer = (iBusCyc_Type == `WB_SIMPLE_WRITE_CYCLE) ? iDat_O_Pointer : iAdr_O_Pointer;
//------------------------------------------------------------------------------
MEM2WBMUnitB MEMToWBM
(
.Clock( Clock ),
.Reset( Reset ),
.iEnable( iEnable & (~iAdr_O_Type | iBusCyc_Type) ),
.iMEMDataPointer( w2MEMToWBM_DataPointer ),
.iMEMDataPointer2( iAdr_O_Pointer ),
.iReadDataBus( iReadDataBus ), //3 Elements comming from DMEM
.iReadDataBus2( iReadDataBus2 ),
.oReadDataElement( wMEMToWBM2__ReadDataElement ), //1 out of 3 elements we read
.oReadDataElement2( wMEMToWBM2__ReadDataElement2 ), //1 out of 3 elements we read
.oDataReadAddress( oDataReadAddress ),
.oDataReadAddress2( oDataReadAddress2 ),
.oDataWriteEnable( wAddrerssSelector2_oDataWriteEnable ), //Always zero
.oDataAvailable( wMEMToWBM_2__Enable ), //Data from MEM available
.iRequestNextElement( w2MEMToWBM_BusOperationComplete ),
.iDataInitialStorageAddress( iAdr_DataWriteBack ), ////########
.oDataWriteAddress( wMEMToWBM2_WBMToMEM_RAMWriteAddr ), ////########
.oDone( wMEMToWBM_2__Done )
);
//------------------------------------------------------------------------------
wire [`DATA_ADDRESS_WIDTH-1:0] wTemp1;
assign wWBMToMEM2__oDataWriteAddress = (iAdr_O_Type == `ADR_IMM) ? iAdr_DataWriteBack : wTemp1;
WBM2MEMUnit WBMToMEM
(
.Clock( Clock ),
.Reset( Reset ),
.iEnable( w2WBMToMEM__Enable & (wReadOperation | MST_I) ), //Don't write stuff to MEM unless is Read bus cycle
 
.iStore( iStore | ~iAdr_O_Type ),
.iWriteBack_Set( iWriteBack_Set ),
.iAdr_DataWriteBack(w2WBMToMEM_MEMWriteAddress ),
//.iAdr_DataWriteBack( iAdr_DataWriteBack ),
.iWBMDataAvailable( wWBM_2_WBMToMEM_DataAvailable ),
.iWBMData( wWBM_2_WBMToMEM_Data ),
 
.oDataBus( wWBMToMEM2__oDataBus ),
.oData( oData ),
.oEnableWBM( wWBMToMEM_2_WBM_Enable ),
.oDataWriteAddress( wTemp1 ),///*******************!!!!!!!!!!!!!!
.oDataWriteEnable( wWBMToMEM2__oDataWriteEnable ),
.oDone( wWBMToMEM2__Done )
);
 
 
 
wire [`WIDTH-1:0] wADR_O_InitialAddress;
assign wADR_O_InitialAddress = (iBusCyc_Type == `WB_SIMPLE_WRITE_CYCLE) ? wMEMToWBM2__ReadDataElement2 : wMEMToWBM_2__Address;
wire wIncrement_Address_O;
assign wIncrement_Address_O = iEnable & ACK_I;
 
 
 
wire wMEMToWBM2__Done;
wire wMEMToWBM2__Trigger;
wire[`WB_WIDTH-1:0] wMEMToWBM_2_Data;
wire w2MEMToWBM__Trigger;
wire wWBM2_MEMToWBM_DataWriteDone;
 
 
wire w2WBM_iEnable;
//wire wWBMEnable_tempWire;
//assign wWBMEnable_tempWire = (iAdr_O_Type == `ADR_IMM) ? wWBMToMEM_2_WBM_Enable;
//assign w2WBM_iEnable = (iBusCyc_Type == `WB_SIMPLE_WRITE_CYCLE) ? wMEMToWBM_2__Enable : wWBMToMEM_2_WBM_Enable;
assign w2WBM_iEnable = (iBusCyc_Type == `WB_SIMPLE_WRITE_CYCLE) ? wMEMToWBM_2__Enable : iEnable;
//assign w2WBM_iEnable = iEnable;// & wWBMToMEM_2_WBM_Enable;
//------------------------------------------------------------------------------
wire wSTB_O;
 
//If the address is a pointer, we need 1 cycle to read the data back from MEM
//before we can the set the value into WBM
wire wAddress_Set_Delayed;
FFD_POSEDGE_SYNCRONOUS_RESET # (1) FFD32_SetDelay
(
.Clock( Clock ),
.Reset( Reset ),
.Enable( 1'b1 ),
.D( iAdr_O_Set ),
.Q( wAddress_Set_Delayed )
);
 
//If the Addr is IMM then just set it whenever iAdr_O_Set is set, but if we have a pointer, then use
//wAddress_Set_Delayed at the beginning and then wWBMToMEM2__Done
wire wWBM_iAddress_Set = (iAdr_O_Type == `ADR_POINTER) ? (wAddress_Set_Delayed | wWBMToMEM2__Done) : iAdr_O_Set;
 
assign STB_O = wSTB_O & ~oDone;
 
WishBoneMasterUnit WBM
(
.CLK_I( Clock ),
.RST_I( Reset ),
.DAT_I( DAT_I ),
.DAT_O( DAT_O ),
.ACK_I( ACK_I ),
.ADR_O( ADR_O ),
.WE_O( WE_O ),
.STB_O( wSTB_O ),
.CYC_O( CYC_O ),
.TGC_O( TGC_O ),
.iEnable( w2WBM_iEnable ),
.iBusCyc_Type( iBusCyc_Type ),
.iAddress_Set( wWBM_iAddress_Set ),//ERROR!!!!!!!!!! we should have: wWBMToMEM2__Done
.iAddress( wADR_O_InitialAddress ),
.oDataReady( wWBM_2_WBMToMEM_DataAvailable ),
.iData( wMEMToWBM2__ReadDataElement ),
.oData( wWBM_2_WBMToMEM_Data )
);
//------------------------------------------------------------------------------
WishBoneSlaveUnit WBS
(
 
.CLK_I( Clock ),
.RST_I( Reset ),
.STB_I( STB_I ),
.WE_I( WE_I ),
.DAT_I( DAT_I ),
.ADR_I( ADR_I ),
.TGA_I( TGA_I ),
.ACK_O( ACK_O ),
.CYC_I( CYC_I ),
.MST_I( MST_I ),
.oDataBus( wWBSToMEM2__oDataBus ),
.oInstructionBus( oInstructionBus ),
.oDataWriteAddress( wWBSToMEM2__oDataWriteAddress ),
.oDataWriteEnable( wWBSToMEM2__oDataWriteEnable ),
.oInstructionWriteAddress( oInstructionWriteAddress ),
.oInstructionWriteEnable( oInstructionWriteEnable )
 
 
);
//------------------------------------------------------------------------------
 
 
endmodule
//--------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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