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

Subversion Repositories theia_gpu

[/] [theia_gpu/] [branches/] [icarus_version/] [rtl/] [Unit_MEM.v] - Diff between revs 166 and 174

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 166 Rev 174
`timescale 1ns / 1ps
`timescale 1ns / 1ps
`include "aDefinitions.v"
`include "aDefinitions.v"
 
`ifdef VERILATOR
 
`include "Module_RAM.v"
 
`include "Module_ROM.v"
 
`include "Module_SwapMemory.v"
 
`include "Module_ControlRegister.v"
 
`endif
/**********************************************************************************
/**********************************************************************************
Theia, Ray Cast Programable graphic Processing Unit.
Theia, Ray Cast Programable graphic Processing Unit.
Copyright (C) 2010  Diego Valverde (diego.valverde.g@gmail.com)
Copyright (C) 2010  Diego Valverde (diego.valverde.g@gmail.com)
 
 
This program is free software; you can redistribute it and/or
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
of the License, or (at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 
***********************************************************************************/
***********************************************************************************/
/*
/*
The memory unit has all the memory related modules for THEIA.
The memory unit has all the memory related modules for THEIA.
There a 3 memories in the core:
There a 3 memories in the core:
DMEM: The data memory, it is a R/W dual channel RAM, stores the data locations.
DMEM: The data memory, it is a R/W dual channel RAM, stores the data locations.
IMEM: The instruction memory, R/W dual channel RAM, stores user shaders.
IMEM: The instruction memory, R/W dual channel RAM, stores user shaders.
IROM: RO instruction memory, stores default shaders and other internal code.
IROM: RO instruction memory, stores default shaders and other internal code.
I use two ROMs with the same data, so that simulates dual channel.
I use two ROMs with the same data, so that simulates dual channel.
This unit also has a Control register.
This unit also has a Control register.
*/
*/
`define USER_CODE_ENABLED 2
`define USER_CODE_ENABLED 2
//-------------------------------------------------------------------
//-------------------------------------------------------------------
module MemoryUnit
module MemoryUnit
(
(
input wire                              Clock,
input wire                              Clock,
input wire                              Reset,
input wire                              Reset,
input wire                                  iFlipMemory,
input wire                                  iFlipMemory,
 
 
//Data bus for EXE Unit
//Data bus for EXE Unit
input wire                              iDataWriteEnable_EXE,
input wire                              iDataWriteEnable_EXE,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress1_EXE,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress1_EXE,
output wire[`DATA_ROW_WIDTH-1:0]        oData1_EXE,
output wire[`DATA_ROW_WIDTH-1:0]        oData1_EXE,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress2_EXE,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress2_EXE,
output wire[`DATA_ROW_WIDTH-1:0]        oData2_EXE,
output wire[`DATA_ROW_WIDTH-1:0]        oData2_EXE,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataWriteAddress_EXE,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataWriteAddress_EXE,
input wire[`DATA_ROW_WIDTH-1:0]         iData_EXE,
input wire[`DATA_ROW_WIDTH-1:0]         iData_EXE,
 
 
//Data bus for IO Unit
//Data bus for IO Unit
input wire                              iDataWriteEnable_IO,
input wire                              iDataWriteEnable_IO,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress1_IO,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress1_IO,
output wire[`DATA_ROW_WIDTH-1:0]        oData1_IO,
output wire[`DATA_ROW_WIDTH-1:0]        oData1_IO,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress2_IO,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress2_IO,
output wire[`DATA_ROW_WIDTH-1:0]        oData2_IO,
output wire[`DATA_ROW_WIDTH-1:0]        oData2_IO,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataWriteAddress_IO,
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataWriteAddress_IO,
input wire[`DATA_ROW_WIDTH-1:0]         iData_IO,
input wire[`DATA_ROW_WIDTH-1:0]         iData_IO,
 
 
//Instruction bus
//Instruction bus
input wire                              iInstructionWriteEnable,
input wire                              iInstructionWriteEnable,
input  wire [`ROM_ADDRESS_WIDTH-1:0]    iInstructionReadAddress1,
input  wire [`ROM_ADDRESS_WIDTH-1:0]    iInstructionReadAddress1,
input  wire [`ROM_ADDRESS_WIDTH-1:0]    iInstructionReadAddress2,
input  wire [`ROM_ADDRESS_WIDTH-1:0]    iInstructionReadAddress2,
input wire [`ROM_ADDRESS_WIDTH-1:0]     iInstructionWriteAddress,
input wire [`ROM_ADDRESS_WIDTH-1:0]     iInstructionWriteAddress,
input wire [`INSTRUCTION_WIDTH-1:0]     iInstruction,
input wire [`INSTRUCTION_WIDTH-1:0]     iInstruction,
output wire [`INSTRUCTION_WIDTH-1:0]    oInstruction1,
output wire [`INSTRUCTION_WIDTH-1:0]    oInstruction1,
output wire [`INSTRUCTION_WIDTH-1:0]    oInstruction2,
output wire [`INSTRUCTION_WIDTH-1:0]    oInstruction2,
 
 
`ifdef DEBUG
`ifdef DEBUG
input wire [`MAX_CORES-1:0]            iDebug_CoreID,
input wire [`MAX_CORES-1:0]            iDebug_CoreID,
`endif
`endif
 
 
 
 
//Control Register
//Control Register
input wire[15:0]                       iControlRegister,
input wire[15:0]                       iControlRegister,
output wire[15:0]                       oControlRegister
output wire[15:0]                       oControlRegister
 
 
 
 
);
);
 
 
wire [`ROM_ADDRESS_WIDTH-1:0] wROMInstructionAddress,wRAMInstructionAddress;
wire [`ROM_ADDRESS_WIDTH-1:0] wROMInstructionAddress,wRAMInstructionAddress;
wire [`INSTRUCTION_WIDTH-1:0] wIMEM2_IMUX__DataOut1,wIMEM2_IMUX__DataOut2,
wire [`INSTRUCTION_WIDTH-1:0] wIMEM2_IMUX__DataOut1,wIMEM2_IMUX__DataOut2,
wIROM2_IMUX__DataOut1,wIROM2_IMUX__DataOut2;
wIROM2_IMUX__DataOut1,wIROM2_IMUX__DataOut2;
wire wFlipSelect;
wire wFlipSelect;
 
 
wire wInstructionSelector,wInstructionSelector2;
wire wInstructionSelector,wInstructionSelector2;
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD1
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD1
(
(
        .Clock(Clock),
        .Clock(Clock),
        .Reset(Reset),
        .Reset(Reset),
        .Enable( 1'b1 ),
        .Enable( 1'b1 ),
        .D( iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-1]  ),
        .D( iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-1]  ),
        .Q( wInstructionSelector )
        .Q( wInstructionSelector )
);
);
 
 
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD2
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD2
(
(
        .Clock(Clock),
        .Clock(Clock),
        .Reset(Reset),
        .Reset(Reset),
        .Enable( 1'b1 ),
        .Enable( 1'b1 ),
        .D( iInstructionReadAddress2[`ROM_ADDRESS_WIDTH-1]  ),
        .D( iInstructionReadAddress2[`ROM_ADDRESS_WIDTH-1]  ),
        .Q( wInstructionSelector2 )
        .Q( wInstructionSelector2 )
);
);
 
 
assign oInstruction1 = (wInstructionSelector == 1) ?
assign oInstruction1 = (wInstructionSelector == 1) ?
        wIMEM2_IMUX__DataOut1 : wIROM2_IMUX__DataOut1;
        wIMEM2_IMUX__DataOut1 : wIROM2_IMUX__DataOut1;
 
 
 
 
assign oInstruction2 = (wInstructionSelector2 == 1) ?
assign oInstruction2 = (wInstructionSelector2 == 1) ?
        wIMEM2_IMUX__DataOut2 : wIROM2_IMUX__DataOut2;
        wIMEM2_IMUX__DataOut2 : wIROM2_IMUX__DataOut2;
//-------------------------------------------------------------------
//-------------------------------------------------------------------
 
 
wire wDataWriteEnable_RMEM,wDataWriteEnable_SMEM,wDataWriteEnable_XMEM;
wire wDataWriteEnable_RMEM,wDataWriteEnable_SMEM,wDataWriteEnable_XMEM;
wire [`DATA_ROW_WIDTH-1:0] wData_SMEM1,wData_SMEM2;
wire [`DATA_ROW_WIDTH-1:0] wData_SMEM1,wData_SMEM2;
wire [`DATA_ROW_WIDTH-1:0] wData_RMEM1,wData_RMEM2,wData_IMEM1,wData_IMEM2,wData_XMEM1,wData_XMEM2;
wire [`DATA_ROW_WIDTH-1:0] wData_RMEM1,wData_RMEM2,wData_IMEM1,wData_IMEM2,wData_XMEM1,wData_XMEM2;
wire [`DATA_ROW_WIDTH-1:0] wIOData_SMEM1,wIOData_SMEM2;//,wData_OMEM1,wData_OMEM2;
wire [`DATA_ROW_WIDTH-1:0] wIOData_SMEM1,wIOData_SMEM2;//,wData_OMEM1,wData_OMEM2;
 
 
/*******************************************************
/*******************************************************
The Data memory is divided into several memory banks.
The Data memory is divided into several memory banks.
Each Bank has different characteristics:
Each Bank has different characteristics:
 
 
* IO MEM: Input Registers, Written by IO, Read by EXE.
* IO MEM: Input Registers, Written by IO, Read by EXE.
* SWAP MEM: Swap registers, while IO reads/write values,
* SWAP MEM: Swap registers, while IO reads/write values,
  EXE reads/write values.
  EXE reads/write values.
* C1-C7, R1- R12: General purpose registers,
* C1-C7, R1- R12: General purpose registers,
  EXE can R/W, IO can not see these sections of the memory
  EXE can R/W, IO can not see these sections of the memory
* OREG*: Output registers written by EXE, Read by IO.
* OREG*: Output registers written by EXE, Read by IO.
 
 
Whenever an input address is received, this imput address
Whenever an input address is received, this imput address
is divided in a bank selector and offset in the following way:
is divided in a bank selector and offset in the following way:
 
 
  __________________________
  __________________________
  | b6 b5 | b4 b3 b2 b1 b0 |
  | b6 b5 | b4 b3 b2 b1 b0 |
 
 
The bits b4 .. b0 are the LSB of the address, this give the
The bits b4 .. b0 are the LSB of the address, this give the
position relative to the bank
position relative to the bank
 
 
The bits b6 and b5 give the actual Bank to select.
The bits b6 and b5 give the actual Bank to select.
Please see aDefinitions.v for a description of each
Please see aDefinitions.v for a description of each
register location.
register location.
 
 
       0____________________
       0____________________
        |      IO MEM      |
        |      IO MEM      |
        |                  |
        |                  |
        |                  | b6b5 = 00
        |                  | b6b5 = 00
      32|__________________|
      32|__________________|
        |     SWAP MEM     |
        |     SWAP MEM     |
        |                  | b6b5 = 01
        |                  | b6b5 = 01
        |                  |
        |                  |
      64|__________________|
      64|__________________|
        |     C1 - C7      |
        |     C1 - C7      |
        |     R1 - R12     | b6b5 = 10
        |     R1 - R12     | b6b5 = 10
        |                  |
        |                  |
      96|__________________|
      96|__________________|
        |     CREG*        |
        |     CREG*        |
        |                  | b6b5 = 11
        |                  | b6b5 = 11
        |                  |
        |                  |
        |__________________|
        |__________________|
 
 
 
 
*******************************************************/
*******************************************************/
 
 
 
 
 
 
MUXFULLPARALELL_2SEL_GENERIC # ( `DATA_ROW_WIDTH ) MUX1
MUXFULLPARALELL_2SEL_GENERIC # ( `DATA_ROW_WIDTH ) MUX1
 (
 (
 .Sel( iDataReadAddress1_EXE[6:5] ),
 .Sel( iDataReadAddress1_EXE[6:5] ),
 .I1( wData_IMEM1                ), //IO MEM
 .I1( wData_IMEM1                ), //IO MEM
 .I2( wData_SMEM1                ), //SWAP MEM
 .I2( wData_SMEM1                ), //SWAP MEM
 .I3( wData_RMEM1                ), //R*, C*
 .I3( wData_RMEM1                ), //R*, C*
 .I4( wData_XMEM1                ), //CREG*
 .I4( wData_XMEM1                ), //CREG*
 .O1( oData1_EXE                 )
 .O1( oData1_EXE                 )
 );
 );
 
 
 
 
MUXFULLPARALELL_2SEL_GENERIC # ( `DATA_ROW_WIDTH ) MUX2
MUXFULLPARALELL_2SEL_GENERIC # ( `DATA_ROW_WIDTH ) MUX2
 (
 (
 .Sel( iDataReadAddress2_EXE[6:5] ),
 .Sel( iDataReadAddress2_EXE[6:5] ),
 .I1( wData_IMEM2                ), //IO MEM
 .I1( wData_IMEM2                ), //IO MEM
 .I2( wData_SMEM2                ), //SWAP MEM
 .I2( wData_SMEM2                ), //SWAP MEM
 .I3( wData_RMEM2                ), //R*, C*
 .I3( wData_RMEM2                ), //R*, C*
 .I4( wData_XMEM2                ), //CREG*
 .I4( wData_XMEM2                ), //CREG*
 .O1( oData2_EXE                 )
 .O1( oData2_EXE                 )
 );
 );
 
 
assign wDataWriteEnable_SMEM = ( iDataWriteAddress_EXE[6:5] == 2'b01 && iDataWriteEnable_EXE ); //Enable WE for SMEM if bank == 01
assign wDataWriteEnable_SMEM = ( iDataWriteAddress_EXE[6:5] == 2'b01 && iDataWriteEnable_EXE ); //Enable WE for SMEM if bank == 01
assign wDataWriteEnable_RMEM = ( iDataWriteAddress_EXE[6:5] == 2'b10 && iDataWriteEnable_EXE); //Enable WE for RMEM if bank == 10
assign wDataWriteEnable_RMEM = ( iDataWriteAddress_EXE[6:5] == 2'b10 && iDataWriteEnable_EXE); //Enable WE for RMEM if bank == 10
assign wDataWriteEnable_XMEM = ( iDataWriteAddress_EXE[6:5] == 2'b11 && iDataWriteEnable_EXE); //Enable WE for RMEM if bank == 11
assign wDataWriteEnable_XMEM = ( iDataWriteAddress_EXE[6:5] == 2'b11 && iDataWriteEnable_EXE); //Enable WE for RMEM if bank == 11
 
 
 
 
//Input Registers, Written by IO, Read by EXE
//Input Registers, Written by IO, Read by EXE
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,5,/*42*/32) IMEM //16 here is enough, I hate small devices!
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,5,/*42*/32) IMEM //16 here is enough, I hate small devices!
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .iWriteEnable(  iDataWriteEnable_IO        ), //Only IO can write into this bank
        .iWriteEnable(  iDataWriteEnable_IO        ), //Only IO can write into this bank
        .iReadAddress0( iDataReadAddress1_EXE[4:0] ), //EXE read address channel 1
        .iReadAddress0( iDataReadAddress1_EXE[4:0] ), //EXE read address channel 1
        .iReadAddress1( iDataReadAddress2_EXE[4:0] ), //EXE read address channel 2
        .iReadAddress1( iDataReadAddress2_EXE[4:0] ), //EXE read address channel 2
        .iWriteAddress( iDataWriteAddress_IO[4:0]  ), //Only IO can write into this bank
        .iWriteAddress( iDataWriteAddress_IO[4:0]  ), //Only IO can write into this bank
        .iDataIn( iData_IO ),
        .iDataIn( iData_IO ),
        .oDataOut0( wData_IMEM1 ),
        .oDataOut0( wData_IMEM1 ),
        .oDataOut1( wData_IMEM2 )
        .oDataOut1( wData_IMEM2 )
);
);
 
 
//Swap registers, while IO reads/write values, EXE reads/write values
//Swap registers, while IO reads/write values, EXE reads/write values
//the pointers get filped in the next iteration
//the pointers get filped in the next iteration
`define SWAP_MEM_ADDR_WIDHT 5
`define SWAP_MEM_ADDR_WIDHT 5
SWAP_MEM  # (`DATA_ROW_WIDTH,5,32) SMEM
SWAP_MEM  # (`DATA_ROW_WIDTH,5,32) SMEM
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .iSelect( wFlipSelect ),
        .iSelect( wFlipSelect ),
 
 
        .iWriteEnableA( wDataWriteEnable_SMEM ),
        .iWriteEnableA( wDataWriteEnable_SMEM ),
        .iReadAddressA0( iDataReadAddress1_EXE[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iReadAddressA0( iDataReadAddress1_EXE[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iReadAddressA1( iDataReadAddress2_EXE[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iReadAddressA1( iDataReadAddress2_EXE[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iWriteAddressA( iDataWriteAddress_EXE[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iWriteAddressA( iDataWriteAddress_EXE[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iDataInA( iData_EXE ),
        .iDataInA( iData_EXE ),
        .oDataOutA0( wData_SMEM1 ),
        .oDataOutA0( wData_SMEM1 ),
        .oDataOutA1( wData_SMEM2 ),
        .oDataOutA1( wData_SMEM2 ),
 
 
        .iWriteEnableB( iDataWriteEnable_IO ),
        .iWriteEnableB( iDataWriteEnable_IO ),
        .iReadAddressB0( iDataReadAddress1_IO[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iReadAddressB0( iDataReadAddress1_IO[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iReadAddressB1( iDataReadAddress2_IO[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iReadAddressB1( iDataReadAddress2_IO[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iWriteAddressB( iDataWriteAddress_IO[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iWriteAddressB( iDataWriteAddress_IO[`SWAP_MEM_ADDR_WIDHT-1:0] ),
        .iDataInB( iData_IO )
        .iDataInB( iData_IO )
//      .oDataOutB0( wIOData_SMEM1 ),
//      .oDataOutB0( wIOData_SMEM1 ),
//      .oDataOutB1( wIOData_SMEM2 )
//      .oDataOutB1( wIOData_SMEM2 )
 
 
);
);
 
 
//General purpose registers, EXE can R/W, IO can not see these sections
//General purpose registers, EXE can R/W, IO can not see these sections
//of the memory
//of the memory
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,5,32) RMEM //Ok so we have fewer Registers then...
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,5,32) RMEM //Ok so we have fewer Registers then...
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .iWriteEnable( wDataWriteEnable_RMEM ),
        .iWriteEnable( wDataWriteEnable_RMEM ),
        .iReadAddress0( iDataReadAddress1_EXE[4:0] ),
        .iReadAddress0( iDataReadAddress1_EXE[4:0] ),
        .iReadAddress1( iDataReadAddress2_EXE[4:0] ),
        .iReadAddress1( iDataReadAddress2_EXE[4:0] ),
        .iWriteAddress( iDataWriteAddress_EXE[4:0] ),
        .iWriteAddress( iDataWriteAddress_EXE[4:0] ),
        .iDataIn( iData_EXE ),
        .iDataIn( iData_EXE ),
        .oDataOut0( wData_RMEM1 ),
        .oDataOut0( wData_RMEM1 ),
        .oDataOut1( wData_RMEM2 )
        .oDataOut1( wData_RMEM2 )
);
);
 
 
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,5,32) XMEM //Ok so we have fewer Registers then...
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,5,32) XMEM //Ok so we have fewer Registers then...
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .iWriteEnable( wDataWriteEnable_XMEM ),
        .iWriteEnable( wDataWriteEnable_XMEM ),
        .iReadAddress0( iDataReadAddress1_EXE[4:0] ),
        .iReadAddress0( iDataReadAddress1_EXE[4:0] ),
        .iReadAddress1( iDataReadAddress2_EXE[4:0] ),
        .iReadAddress1( iDataReadAddress2_EXE[4:0] ),
        .iWriteAddress( iDataWriteAddress_EXE[4:0] ),
        .iWriteAddress( iDataWriteAddress_EXE[4:0] ),
        .iDataIn( iData_EXE ),
        .iDataIn( iData_EXE ),
        .oDataOut0( wData_XMEM1 ),
        .oDataOut0( wData_XMEM1 ),
        .oDataOut1( wData_XMEM2 )
        .oDataOut1( wData_XMEM2 )
);
);
 
 
 
 
UPCOUNTER_POSEDGE # (1) UPC1
UPCOUNTER_POSEDGE # (1) UPC1
(
(
.Clock(Clock),
.Clock(Clock),
.Reset( Reset ),
.Reset( Reset ),
.Initial(1'b0),
.Initial(1'b0),
.Enable(iFlipMemory),
.Enable(iFlipMemory),
.Q(wFlipSelect)
.Q(wFlipSelect)
);
);
 
 
 
 
 
 
//-------------------------------------------------------------------
//-------------------------------------------------------------------
/*
/*
Instruction memory.
Instruction memory.
*/
*/
 
 
// ROM_ADDRESS_WIDTH exceds the array size it may get trimmed...
// ROM_ADDRESS_WIDTH exceds the array size it may get trimmed...
RAM_DUAL_READ_PORT  # (`INSTRUCTION_WIDTH,`ROM_ADDRESS_WIDTH,/*512*/128) INST_MEM //Only 128 instructions :( well this is for the user anyway
RAM_DUAL_READ_PORT  # (`INSTRUCTION_WIDTH,`ROM_ADDRESS_WIDTH,/*512*/128) INST_MEM //Only 128 instructions :( well this is for the user anyway
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .iWriteEnable( iInstructionWriteEnable ),
        .iWriteEnable( iInstructionWriteEnable ),
        .iReadAddress0( {1'b0,iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-2:0]} ),
        .iReadAddress0( {1'b0,iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-2:0]} ),
        .iReadAddress1( {1'b0,iInstructionReadAddress2[`ROM_ADDRESS_WIDTH-2:0]} ),
        .iReadAddress1( {1'b0,iInstructionReadAddress2[`ROM_ADDRESS_WIDTH-2:0]} ),
        .iWriteAddress( iInstructionWriteAddress ),
        .iWriteAddress( iInstructionWriteAddress ),
        .iDataIn( iInstruction ),
        .iDataIn( iInstruction ),
        .oDataOut0( wIMEM2_IMUX__DataOut1 ),
        .oDataOut0( wIMEM2_IMUX__DataOut1 ),
        .oDataOut1( wIMEM2_IMUX__DataOut2 )
        .oDataOut1( wIMEM2_IMUX__DataOut2 )
 
 
);
);
//-------------------------------------------------------------------
//-------------------------------------------------------------------
/*
/*
 Default code stored in ROM.
 Default code stored in ROM.
*/
*/
wire [`INSTRUCTION_WIDTH-1:0] wRomDelay1,wRomDelay2;
wire [`INSTRUCTION_WIDTH-1:0] wRomDelay1,wRomDelay2;
//In real world ROM will take at least 1 clock cycle,
//In real world ROM will take at least 1 clock cycle,
//since ROMs are not syhtethizable, I won't hurt to put
//since ROMs are not syhtethizable, I won't hurt to put
//this delay
//this delay
 
 
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_WIDTH ) FFDA
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_WIDTH ) FFDA
(
(
        .Clock(Clock),
        .Clock(Clock),
        .Reset(Reset),
        .Reset(Reset),
        .Enable(1'b1),
        .Enable(1'b1),
        .D(wRomDelay1),
        .D(wRomDelay1),
        .Q(wIROM2_IMUX__DataOut1 )
        .Q(wIROM2_IMUX__DataOut1 )
);
);
 
 
 
 
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_WIDTH ) FFDB
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_WIDTH ) FFDB
(
(
        .Clock(Clock),
        .Clock(Clock),
        .Reset(Reset),
        .Reset(Reset),
        .Enable(1'b1),
        .Enable(1'b1),
        .D(wRomDelay2),
        .D(wRomDelay2),
        .Q(wIROM2_IMUX__DataOut2 )
        .Q(wIROM2_IMUX__DataOut2 )
);
);
 
 
//The reason I put two ROMs is because I need to read 2 different Instruction 
//The reason I put two ROMs is because I need to read 2 different Instruction 
//addresses at the same time (branch-taken and branch-not-taken) and not sure
//addresses at the same time (branch-taken and branch-not-taken) and not sure
//how to write dual read channel ROM this way...
//how to write dual read channel ROM this way...
 
 
ROM IROM
ROM IROM
(
(
        .Address( {1'b0,iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-2:0]} ),
        .Address( {1'b0,iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-2:0]} ),
        `ifdef DEBUG
        `ifdef DEBUG
        .iDebug_CoreID(iDebug_CoreID),
        .iDebug_CoreID(iDebug_CoreID),
        `endif
        `endif
        .I( wRomDelay1 )
        .I( wRomDelay1 )
);
);
 
 
ROM IROM2
ROM IROM2
(
(
        .Address( {1'b0,iInstructionReadAddress2[`ROM_ADDRESS_WIDTH-2:0]} ),
        .Address( {1'b0,iInstructionReadAddress2[`ROM_ADDRESS_WIDTH-2:0]} ),
        `ifdef DEBUG
        `ifdef DEBUG
        .iDebug_CoreID(iDebug_CoreID),
        .iDebug_CoreID(iDebug_CoreID),
        `endif
        `endif
        .I( wRomDelay2 )
        .I( wRomDelay2 )
);
);
//--------------------------------------------------------
//--------------------------------------------------------
ControlRegister CR
ControlRegister CR
(
(
        .Clock( Clock ),
        .Clock( Clock ),
        .Reset( Reset ),
        .Reset( Reset ),
        .iControlRegister( iControlRegister ),
        .iControlRegister( iControlRegister ),
        .oControlRegister( oControlRegister )
        .oControlRegister( oControlRegister )
);
);
 
 
 
 
endmodule
endmodule
//-------------------------------------------------------------------
//-------------------------------------------------------------------
 No newline at end of file
 No newline at end of file
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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