Построение однотактного простейшего ядра RISC-V
Вариант кода описания модуля:
module rv_mem
#(
parameter DATA_WIDTH=32,
parameter ADDR_WIDTH=10
)
( input clk,
input [(ADDR_WIDTH-1):0] i_addr,
output reg [(DATA_WIDTH-1):0] code_out,
input [(ADDR_WIDTH-1):0] d_addr,
output reg [(DATA_WIDTH-1):0] d_out,
input [(DATA_WIDTH-1):0] d_in,
input we
);
// ROM array
reg [DATA_WIDTH-1:0] rom [0:2**ADDR_WIDTH-1] ;
// read ROM content from file
initial
$readmemh("rom.txt",rom);
always @ (posedge clk)
begin
if (we) rom[d_addr] <= d_in;
end
always @ (*)
begin
code_out <= rom[i_addr];
end
endmodule
В некоторых случаях удобнее будет реализовать две отдельные памяти - память для кода, память для данных - как некие сильно упрощенные варианты кэша инструкций и кэша данных.
Общая структура процессора (вместе с блоками памятей - и программ и данных) представлена на рис.5.2. Блоки выстроены в условно-линейном порядке прохождения сигнала, сквозные сигналы также проброшены вдоль блоков. Это один из портов блока памяти rv_mem адресуется программным счетчиком (выход РС), соответствующее выходное слово инструкции - iw поступает параллельно на входы модулей rv_desh и rv_imm. Данные модули "разбирают" поступившую инструкцию выделяя из нее адреса регистров-операндов файл-регистра, формируют непосредственное числовое значение (immediate), сопровождая декодированные элементами сигналами стробов.
Значения выбранных регистров регистрового файла, числовое значение (immediate), программный счетчик, значения выбранных регистров специального назначения (опционально) поступают на вход мультиплексора операндов rv_ops_mux, параллельно выхода файл-регистра подаются на вход компаратора (вернее его называть блоков разрешения перехода) совместно с комбинацией опкода с модификаторами (opcode, funct3, funct7).
Парные выходы мультиплексора также вместе с кодами операции поступают на вход АЛУ (модуль rv_alu_v). АЛУ применяется и для выполнения операций над операндами, и для расчета адресов - или адресов переходов, или адресов для обращения к памяти данных (ОЗУ). В зависимости от операции результат АЛУ, инкрементированный программный счетчик (PC+4) или данные из оперативной памяти записывается в регистр с номером rd файл-регистра.
Блок регистров специального назначения добавлен, как опциональный (выделен зелёным цветом).
Выходной сигнал блока сравнения/управления переносом и новое вычисленное значение подаются на соответствующие входы программного счетчика rv_pc.
Возможные недостатки предлагаемого решения:
- операции с памятью становятся критичными и скорее всего их придётся делать за два такта;
- исполнение программного счётчика далеко от "классических" вариантов;
- наличие относительно большого числа "сквозных" сигналов;
- наличие двух достаточно "широких" мультиплексоров - в перспективе (если ее, конечно представлять) масштабирования разрядности реализация процессорного ядра может быть "весомой".
