Memories
This page describes the included Memory components. Memory is
only useful if you can set its initial value, and that's not a trivial task. We
wrote a script that make this process tractable, though not yet easy or
enjoyable. Get this script here.
Module: ROM256x32
In our single-cycle designs we don't need to
write to the instruction memory, so this ROM allows us to write a program with
up to 256 instructions. If the need for larger programs arises they can be
tacked together, but that will make initializing the memory more complex. The actual implementation depends
on the ovi_unisim library.
This component actually consists of 32 256x1
bit ROMs, 1 for each bit in the instruction. Each ROM has its own internal INIT
parameter, and we have provided parameters INIT_C0 through INIT_C31 which are
256 bit hex values that init an entire ROM bit-slice.
Setting the ROM requires updating all
of the INIT_C0 - INIT_C31 parameters appropriately. To make this possible we've
written a script that takes an input in MIPS assembly and outputs the proper
values for the individual INIT_Cn values.
Parameters:
|
|
Name |
Default |
Description |
INIT_C0 |
256'h0 |
initial value for bit 0 of all
256 words |
..... |
.... |
..... |
INIT_C31 |
256'h0 |
initial value for bit 31 of all
256 words |
|
|
|
Port Description:
|
|
Name |
Dir |
Width |
Description |
ADDR |
In |
8 |
Address to read from |
OUTPUT |
OUT |
31 |
Word stored at Address ADDR |
|
|
|
|
|
Notes:
|
|
-
There must be a glbl.GSR signal defined to use this component
|
|
|
Initializing:
|
|
Here's an example of initializing a ROM using
the script asm_to_hex.pl. The program is stored in simple.s
and we'll be generating temporary file simple.rom. The last piece
of information we need is that hierarchical name of the ROM. I'll assume that
the instance of the ROM is named "IROM".
|
- If you haven't already, downloaded the script asm_to_hex.pl
and add it to your design.
- Type the follow command into the Active-HDL
console:
> runscript asm_to_hex.pl -in=simple.s -out=simple.rom -init=ROM -obj=MemorySystem.BIOS.U1_ARRAY%d.INIT
- Now simple.rom looks like this:
defparam
IROM.INIT_C0 =
256'h000...
....
IROM.INIT_C31 =
256'h000...
- If IROM is declared in a Verilog file,
skip to step 6
- Add a module declarations block to
your block diagram (See Active-HDL Help)
- add the following line to the module declarations block:
`include "simple.rom"
|
|
|
Module: Ram256x32_sw_ar_wb
This is the data memory you should use for
Lab1. The reason is that it supports asynchronous reads (output changes when
address changes). This memory has only 256 words. This means that
only the lower 10 bits of your Address will be used. It supports
writing at the byte, half-word, and word level. This is specified by the
value of WE (2'b00 = don't write, 2'b01 = write bits [7:0] into correct byte,
2'10 = write word, 2'b11 = write half-word to upper or lower half.
Parameters:
|
|
Name |
Default |
Description |
INIT |
36'h0 |
The initial output value |
SRVAL |
36'h0 |
The output value when SSR is set |
INIT_00-1F |
256'h0 |
Initialization values. Not USED |
|
|
|
Port Description:
|
|
Name |
Dir |
Width |
Description |
CLK |
In |
1 |
clock signal |
ADDR |
In |
10 |
ADDR to read or write |
DI |
In |
32 |
Data to write |
WE |
In |
2 |
write signals: 2'b01 = write
byte , 2'b10 = write word, 2'b11 = write
half-word |
DO |
Out |
32 |
Data read from memory |
|
|
|
|
|
Notes:
|
|
-
There must be a glbl.GSR signal defined to use this component
|
|
|
|
Initializing:
|
|
Here's an example of initializing a RAM using
the script asm_to_hex.pl. The data is stored in simple.hex
and we'll be generating temporary file simple.ram. The last piece
of information we need is that hierarchical name of the RAM. I'll assume that
the instance of the RAM is named "DRAM".
|
- If you haven't already, downloaded the script asm_to_hex.pl
and add it to your design.
- Type the follow command into the
Active-HDL
console:
> runscript asm_to_hex.pl -in=simple.hex -out=simple.ram -init=ASYNC
-obj=DRAM
- Now simple.ram looks like this:
defparam
DRAM.Byte0.U1.INIT_00 =
32'h000...
....
DRAM.Byte3.U8.INIT_07 =
32'h000...
- If DRAM is declared in a Verilog file,
skip to step 6
- Add a module declarations block to
your block diagram (See Active-HDL Help)
- Add the following code to your
declarations block:
//synopsys translate_off
`include "simple.ram"
//synopsys translate_on
|
|
|
Module: ram_control
This is a small combinational block that
controls byte-level writes in the memory unit we designed. Basically, our memory
consists of 4 banks that are each 1 byte wide. For SW, we simply hit all 4 with
a WE. However, for SB we only want to write to a single byte, and leave the
others unchanged. The ram_control unit makes sure this all happens
correctly.
|
|
Port Description:
|
|
Name |
Dir |
Width |
Description |
ADDR |
In |
2 |
bottom bits of address specify
the byte to write |
WB |
In |
1 |
signals an SB instruction |
WW |
In |
1 |
signals an SW instruction |
B_WE |
Out |
3 |
the WE signals for the
individual memory banks |
|
|
|
|
|
Notes:
|
|
-
This only supports SW and SB.
If you really need SH, ask for help
|
|
|
Module: ramb16_s36_wb
This data memory component consists of 4
blockram elements configured as byte-wide units. This means that there are 2048
words of memory, for a total of 8KB. To enable byte-level writes we use
the ram_control unit described above. These blockram units have
synchronous write, and can be initialized.
NOTE: At release, we can only
init the first 64 words of memory. We'll have a better solution out soon
Parameters:
|
|
Name |
Default |
Description |
INIT |
36'h0 |
The initial output value |
SRVAL |
36'h0 |
The output value when SSR is set |
WRITE_MODE |
"WF" |
determines relationship between
inputs and outputs |
INIT_00-3F |
256'h0 |
Initialization values. Only
INIT_00-07 work NOW |
|
|
|
Port Description:
|
|
Name |
Dir |
Width |
Description |
EN |
In |
1 |
make the memory accessible |
CLK |
In |
1 |
clock signal |
SSR |
In |
1 |
synchronous static reset |
ADDR |
In |
13 |
ADDR to read or write |
DI |
In |
32 |
Data to write |
DIP |
In |
4 |
parity of input data (ignored) |
WE |
In |
2 |
write signals: WE[0] = WB, WE[1]
= WW |
DO |
Out |
32 |
Data read from memory |
DOP |
Out |
4 |
parity of output data (ignored) |
|
|
|
|
|
Notes:
|
|
-
There must be a glbl.GSR signal defined to use this component
|
|
|
|
Initializing:
|
|
Here's an example of initializing a RAM using
the script asm_to_hex.pl. The data is stored in simple.hex
and we'll be generating temporary file simple.ram. The last piece
of information we need is that hierarchical name of the RAM. I'll assume that
the instance of the RAM is named "DRAM".
|
- If you haven't already, downloaded the script asm_to_hex.pl
and add it to your design.
- Type the follow command into the Active-HDL
console:
> runscript asm_to_hex.pl -in=simple.hex -out=simple.ram -init=RAM
\ -obj=DRAM.INIT_%x
- Now simple.ram looks like this:
defparam
DRAM.INIT_00 =
256'h000...
....
DRAM.INIT_3F =
256'h000...
- If DRAM is declared in a Verilog file,
skip to step 6
- Add a module declarations block to
your block diagram (See Active-HDL Help)
- Copy contents of simple.rom into
the file where DRAM is defined.
- Remove old values for DRAM.INIT_0x
|
|
|
Module: Memory_Toplevel
This module contains the entire memory system for the processor that you will be building. It contains a ROM that acts as the BIOS, three asynchronous RAMs that act as Instruction Memory, Data Memory and stack space, and an IO controller that routes signals to and from the various IO devices on the processor. This module manages both instruction and data memory and fetches the appropriate instructions and data based on the addresses provided to it.
Memory space is mapped as follows:
- Instructions
- Addresses 0x00000000 - 0x003FFFFF: Instruction fetched from ROM
- Address above 0x00400000: Instruction fetched from RAM
- Data
- Addresses below 0x10000000: Data read/written to Instruction RAM. Only applicable if instructions are coming from the BIOS.
- Addresses 0x10000000 - 0x7FFEFFFF - Data read/written to Data RAM
- Addresses 0x7FFF0000 - 0x7FFFFFFF - Data read/written to Stack
- Addresses 0x80000000 - 0x800003FF - Data read/written to IO Device 1
- Addresses 0x80000400 - 0x800007FF - Data read/written to IO Device 2
- Addresses 0x80000800 - 0x80000BFF - Data read/written to IO Device 3
- Addresses 0x80000C00 - 0x80000FFF - Data read/written to IO Device 4
|
Port Description:
|
|
Name |
Dir |
Width |
Description |
CLK |
In |
1 |
clock signal |
WE |
In |
2 |
write signals: WE[0] = WB, WE[1] = WW |
InstAddress |
In |
32 |
The address of the instruction that should be fetched |
Data Address |
In |
32 |
The address to read/write data to |
IODev1Input |
In |
32 |
Data in from IO Device 1 |
IODev2Input |
In |
32 |
Data in from IO Device 2 |
IODev3Input |
In |
32 |
Data in from IO Device 3 |
IODev4Input |
In |
32 |
Data in from IO Device 4 |
DataOut |
Out |
32 |
Data read from memory |
Instruction |
Out |
32 |
Instruction read from memory |
IODev1WE |
Out |
2 |
WriteEnable signal for IO Device 1 |
IODev2WE |
Out |
2 |
WriteEnable signal for IO Device 2 |
IODev3WE |
Out |
2 |
WriteEnable signal for IO Device 3 |
IODev4WE |
Out |
2 |
WriteEnable signal for IO Device 4 |
|
|
|
|
|
|
Module: MMU
This module acts as the memory management unit for the memory system on the processor. It routes WE signals and data to the various memory modules and I/O Controller based on the address given to it. It follows the same address conventions as Memory_Toplevel and is a part of it.
|
Port Description:
|
|
Name |
Dir |
Width |
Description |
writeEnable |
In |
2 |
write signals: writeEnable[0] = WB, writeEnable[1] = WW |
InstructionAddress |
In |
32 |
The address of the instruction that should be fetched |
Data Address |
In |
32 |
The address to read/write data to |
ROMAddress |
Out |
8 |
The address to access in the ROM |
InstAddress |
Out |
10 |
The address to access in the IRAM |
StackAddress |
Out |
10 |
The address to access in the Stack |
DataAddress |
Out |
10 |
The address to access in DRAM |
IOAddress |
Out |
10 |
The address to access for the I/O Controller |
InstWE |
Out |
2 |
WriteEnable signal for IRAM |
DataWE |
Out |
2 |
WriteEnable signal for DRAM |
StackWE |
Out |
2 |
WriteEnable signal for Stack |
IOWE |
Out |
2 |
WriteEnable signal for the I/O Controller |
instFromROM |
Out |
1 |
Signal to a mux to indicate if the instruction source is the BIOS or IRAM |
dataTarget |
Out |
2 |
Signal to a mux to indicate if the data is coming from the IRAM, DRAM, Stack or I/O Controller |
|
|
|
|
|
|