Skip to content

Input Buffer

Diogo Valadares Reis dos Santos edited this page Aug 26, 2025 · 2 revisions

[Português]

[← Previous Page | Next Page →]

The 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 Input Buffer

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.

Inside the input buffer

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.

image

# SystemVerilog Code
`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

Clone this wiki locally