-
Notifications
You must be signed in to change notification settings - Fork 0
RAM
The Random Access Memory (RAM) is an external component responsible for storing instructions and data for the system. Although RAM is not an internal component, it is required for the basic functionality of the system.
In DRISC-V, the RAM needs to be byte-addressable, allow read and write operations of words through a bidirectional bus, and be writable with three different data sizes (byte, short, and word) at any arbitrary offset. Word-misaligned data handling is not required by the RAM and is instead managed by the CSR Controller.
The DRISC-V architecture uses Little-Endian, which means that the least significant byte of a word is placed at the lowest address. For example, a NOP (No Operation) instruction, which is encoded as 0x00000013, is stored in memory as 13 00 00 00. Another example is the word 0x76543210, which in Little-Endian would be stored as 10 32 54 76, while in Big-Endian it would be stored as 76 54 32 10. While Big-Endian may seem more intuitive for reading RAM directly, placing the bytes with the largest value at the lowest address does not make much sense and complicates certain processes for the machine. This is why, like most computer systems today, DRISC-V utilizes the Little-Endian format.
The component used for the RAM in Logisim Evolution is native to the tool and does not contain any internal components. Along with the RAM, there is a micro-component called the Address Selector. This component allows a component to receive read-write signals only if the address transmitted by the processor is within a specified range.
In its general form, it can be read as:
wire is_correct_address = (address_bus >= min_address) && (address_bus < max_address);
wire write = write && is_correct_address;
wire read = read && is_correct_address;This micro-component is reused in each IO device, allowing only one to be active at a time.
In real systems, there is usually a component called a cache inside the processor, which serves as faster memory. However, this component has not been implemented in the current version of DRISC-V, and because of that, it is assumed that the RAM (as well as other IO devices) does not contain any delay in its data transmission.
The SystemVerilog code for the RAM contains extra features that allow it to directly load a program from a file every time the simulation is restarted, as well as parameters that allow its size to be modified. The file that initializes the RAM needs to be in a specific format, which will be explained further in the SystemVerilog Simulation page.
`timescale 1s/1s
//Parameters to customized the RAM
module ram #(
parameter MEM_INIT_FILE = "", //The path for the file that will initialize the RAM
parameter ADDR_WIDTH = 12, //How many bits are used for the RAM address
parameter MEM_DEPTH = 1 << ADDR_WIDTH, //How many bytes can be addresses in the memory
parameter PROGRAM_SIZE = MEM_DEPTH //The program file can be smaller then the RAM size, and this parameter allows you to specify its size in bytes
)
//inputs and outputs
(
input clock,
input write,
input read,
input [1:0] data_size, // 00: 1 byte, 01: 2 bytes, 11: 4 bytes
input [ADDR_WIDTH-1 : 0] address,
inout [31:0] data
);
// Memory array
reg [7:0] mem [0:MEM_DEPTH-1];
//If the ram is not being read or is being written to, it should be disconnected from the Data IO Bus.
assign data = (read && !write) ? {mem[address+3], mem[address+2], mem[address+1], mem[address]} : 32'bz;
//Inicializes the ram with a program file, or zeroes if a program is not specified.
initial begin
integer i;
for (i = 0; i < MEM_DEPTH; i = i + 1) begin
mem[i] = 0;
end
if (MEM_INIT_FILE != "") begin
$readmemh(MEM_INIT_FILE, mem, 0, PROGRAM_SIZE-1);
end
end
//Write logic
always @(posedge clock) begin
if (write) begin
case (data_size)
2'b00: mem[address] <= data[7:0];
2'b01: begin
mem[address] <= data[7:0];
mem[address+1] <= data[15:8];
end
2'b10: ; // Invalid case, do nothing
2'b11: begin
mem[address] <= data[7:0];
mem[address+1] <= data[15:8];
mem[address+2] <= data[23:16];
mem[address+3] <= data[31:24];
end
endcase
end
end
endmodule-
- 1.1 Introduction
- 1.2 RISC-V Implementation
- 1.2.1 Available Instruction Set
- 1.2.2 Available Non-ISA Features
-
- 2.1 ALU
- 2.2 Register File
- 2.3 Program Counter
- 2.4 Input Buffer
- 2.5 RAM
- 2.6 Operation Controller
- 2.7 CSR Controller
-
- 3.1 Input Devices
- 3.1.1 Keyboard
- 3.1.2 Switches and Joystick
- 3.1.3 Random Number Generator
- 3.1.4 Real-Time Device
- 3.2 Output Devices
- 3.2.1 Screen
- 3.2.2 Terminal
- 3.2.3 Software Interrupt Register
- 3.1 Input Devices