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 |
//-------------------------------------------------------------------------- |