-
Notifications
You must be signed in to change notification settings - Fork 0
Input Buffer
The Input Buffer in DRISC-V is a remnant of the circuits from the original RISC I that allows data that is loaded from the memory to be shifted and sign-extended. What this means is that load instructions utilize this component to select a portion of the word(4 bytes) that is being loaded from the memory and after selecting this portion, it is extended to 32-bits, while keeping the signal.
The following table shows every possibility of the transformations this component allows, considering the input 0xfafbfcfd:
| Type | Offset | Data Out (hex) | Data Out (dec) |
|---|---|---|---|
| word | 0 | 0xfafbfcfd |
-84,148,995 |
| short unsigned | 0 | 0xfcfd |
64765 |
| short unsigned | 1 | 0xfbfc |
64508 |
| short unsigned | 2 | 0xfafb |
64251 |
| short | 0 | 0xfffffcfd |
-771 |
| short | 1 | 0xfffffbfc |
-1028 |
| short | 2 | 0xfffffafb |
-1285 |
| byte unsigned | 0 | 0xfd |
253 |
| byte unsigned | 1 | 0xfc |
252 |
| byte unsigned | 2 | 0xfb |
251 |
| byte unsigned | 3 | 0xfa |
250 |
| byte | 0 | 0xfffffffd |
-3 |
| byte | 1 | 0xfffffffc |
-4 |
| byte | 2 | 0xfffffffb |
-5 |
| byte | 3 | 0xfffffffa |
-6 |
The Data Type is encoded as follows: the most significant bit indicates whether the data is signed, while the other two bits indicate the size — 00 for byte, 01 for short, and 1x for word.
When the input buffer receives data, it needs to be stored inside its register in order to be decoded. This register is always written during Phase 2 of the pipeline, during the MEM access of load instructions. In the following cycle, the data is shifted using multiple multiplexers. Then, the byte and short lines are extended to 32 bits, and finally, one of the three data sizes is chosen as output.
`timescale 1s/1s
//Inputs and Outputs
module input_buffer(
input clock,
input write,
input [2:0] data_type,
input [1:0] data_offset,
input [31:0] io_in,
output logic [31:0] cpu_out
);
//Register
reg [31:0] data_reg;
//Register update logic
always@(posedge clock) begin
if(write) begin
data_reg <= io_in;
end
end
//Shift and data extension
always@(*) begin
case (data_type)
3'b100: cpu_out = {24'h0, data_reg[data_offset*8+7 -: 8]};
3'b101: cpu_out = {16'h0, data_reg[data_offset*8+15 -: 16]};
3'b000: cpu_out = {{24{data_reg[data_offset*8+7]}}, data_reg[data_offset*8+7 -: 8]};
3'b001: cpu_out = {{16{data_reg[data_offset*8+15]}}, data_reg[data_offset*8+15 -: 16]};
default: cpu_out = data_reg;
endcase
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