mirror of
https://github.com/MPSU/APS.git
synced 2025-09-16 17:40:41 +00:00
ЛР8. Добавление тб и готового модуля
This commit is contained in:
committed by
Andrei Solodovnikov
parent
f667837c48
commit
aa381fc84e
@@ -162,7 +162,7 @@ _Рисунок 1. Место LSU в микроархитектуре RISC-пр
|
||||
|
||||
Предположим, по адресам `16-19` лежит слово `32'hA55A_1881`. Чтение по любому из адресов 16, 17, 18, 19 вернет это слово на входном сигнале `mem_rd_i`. В случае инструкции `LB` (`core_size_i == LDST_B`) по адресу 19 (чтение байта, который интерпретируется как знаковое число), в регистровый файл должно быть записано значение `32'hFFFF_FFA5`, поскольку по 19-ому адресу лежит байт `A5`, который затем будет знакорасширен. В случае той же самой инструкции, но по адресу 18, в регистровый файл будет записано значение `32'h0000_005A` (знакорасширенный байт `5A`, расположенный по 18ому адресу).
|
||||
|
||||
Получить нужный байт можно из входного сигнала `mem_rd_i`, но чтобы понять какие биты этого сигнала нас интересуют, необходимо посмотреть на входные сигналы `core_size_i` и `core_addr_i[1:0]`. `core_size_i` сообщит конкретный тип инструкции (сколько нужно взят байт из считанного слова), а `core_addr_i[1:0]` укажет номер начального байта, который нужно взять из `mem_rd_i`.
|
||||
Получить нужный байт можно из входного сигнала `mem_rd_i`, но чтобы понять какие биты этого сигнала нас интересуют, необходимо посмотреть на входные сигналы `core_size_i` и `core_addr_i[1:0]`. `core_size_i` сообщит конкретный тип инструкции (сколько нужно взять байт из считанного слова), а `core_addr_i[1:0]` укажет номер начального байта, который нужно взять из `mem_rd_i`.
|
||||
|
||||
В случае инструкции `LH` будет все тоже самое, только знакорасширяться будет не байт, а полуслово.
|
||||
|
||||
@@ -229,4 +229,9 @@ _Рисунок 3. Структурная схема модуля `riscv_lsu`_
|
||||
2. Опишите в нем модуль `riscv_lsu` с таким же именем и портами, как указано в [задании](#задание).
|
||||
1. При описании обратите внимание на то, что большая часть модуля является чисто комбинационной. В этом плане реализация модуля будет частично похожа на реализацию декодера.
|
||||
2. Однако помимо комбинационной части, в модуле будет присутствовать и один регистр.
|
||||
3. Проверка модуля будет проведена в рамках работы по интеграции модуля **LSU** в процессорную систему.
|
||||
3. После описания модуля, его необходимо проверить с помощью тестового окружения.
|
||||
1. Тестовое окружение находится [здесь](tb_lsu.sv).
|
||||
2. Для запуска симуляции воспользуйтесь [`этой инструкцией`](../../Vivado%20Basics/Run%20Simulation.md).
|
||||
3. Перед запуском симуляции убедитесь, что в качестве top-level модуля выбран корректный (`tb_lsu`).
|
||||
4. Во время симуляции, вы должны прожать "Run All" и убедиться, что в логе есть сообщение о завершении теста!
|
||||
|
||||
|
322
Labs/08. Load-store unit/tb_lsu.sv
Normal file
322
Labs/08. Load-store unit/tb_lsu.sv
Normal file
@@ -0,0 +1,322 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company: MIET
|
||||
// Engineer: Andrei Solodovnikov
|
||||
|
||||
// Module Name: lsu_testbench
|
||||
// Project Name: RISCV_practicum
|
||||
// Target Devices: Nexys A7-100T
|
||||
// Description: tb for Load&Store module
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
module tb_lsu();
|
||||
import riscv_pkg::*;
|
||||
logic clk_i ;
|
||||
logic rst_i ;
|
||||
logic core_req_i ;
|
||||
logic core_we_i ;
|
||||
logic [ 2:0] core_size_i ;
|
||||
logic [31:0] core_addr_i ;
|
||||
logic [31:0] core_wd_i ;
|
||||
logic [31:0] core_rd_o ;
|
||||
logic core_stall_o ;
|
||||
logic mem_req_o ;
|
||||
logic mem_we_o ;
|
||||
logic [ 3:0] mem_be_o ;
|
||||
logic [31:0] mem_addr_o ;
|
||||
logic [31:0] mem_wd_o ;
|
||||
logic [31:0] mem_rd_i ;
|
||||
logic mem_ready_i ;
|
||||
logic grm_req_o ;
|
||||
logic [31:0] grm_rd_o ;
|
||||
logic grm_stall_o ;
|
||||
logic grm_we_o ;
|
||||
logic [ 3:0] grm_be_o ;
|
||||
logic [31:0] grm_addr_o ;
|
||||
logic [31:0] grm_wd_o ;
|
||||
riscv_lsu dut(.*);
|
||||
|
||||
riscv_lsu_ref grm(
|
||||
.core_rd_o (grm_rd_o ),
|
||||
.core_stall_o (grm_stall_o),
|
||||
.mem_we_o (grm_we_o ),
|
||||
.mem_be_o (grm_be_o ),
|
||||
.mem_addr_o (grm_addr_o ),
|
||||
.mem_wd_o (grm_wd_o ),
|
||||
.mem_req_o (grm_req_o ),
|
||||
.*
|
||||
);
|
||||
|
||||
|
||||
|
||||
always #5 clk_i <= ~clk_i;
|
||||
|
||||
int err_count;
|
||||
bit not_stopped;
|
||||
initial begin
|
||||
$display("\n\n===========================\n\nPress button 'Run All' (F3)\n\n===========================\n\n");
|
||||
$stop();
|
||||
err_count = 0;
|
||||
not_stopped = 1;
|
||||
clk_i <= 0;
|
||||
rst_i <= 1'b1;
|
||||
repeat(2)@(posedge clk_i);
|
||||
rst_i <= 1'b0;
|
||||
repeat(3e3)@(posedge clk_i);
|
||||
$display("Simulation finished. Number of errors: %d", err_count);
|
||||
$finish();
|
||||
end
|
||||
|
||||
initial begin
|
||||
core_req_i = '0;
|
||||
core_we_i = '0;
|
||||
core_size_i = '0;
|
||||
core_addr_i = '0;
|
||||
core_wd_i = '0;
|
||||
mem_rd_i = '0;
|
||||
mem_ready_i = '0;
|
||||
repeat(4)@(posedge clk_i);
|
||||
forever begin
|
||||
if((err_count >= 10) && not_stopped) begin
|
||||
$display("Simulation stopped after ten errors.");
|
||||
$stop();
|
||||
not_stopped = 0;
|
||||
end
|
||||
@(posedge clk_i);
|
||||
if(!core_stall_o) begin
|
||||
core_req_i = $random;
|
||||
core_we_i = $random;
|
||||
if(core_we_i) begin
|
||||
assert(std::randomize(core_size_i) with {core_size_i inside {LDST_B,LDST_H,LDST_W};});
|
||||
end else begin
|
||||
assert(std::randomize(core_size_i) with {core_size_i inside {LDST_B,LDST_H,LDST_W,LDST_BU,LDST_HU};});
|
||||
end
|
||||
core_addr_i = $random;
|
||||
core_wd_i = $random;
|
||||
mem_rd_i = $random;
|
||||
end
|
||||
mem_ready_i = $random;
|
||||
end
|
||||
end
|
||||
|
||||
logic is_reading, is_writing;
|
||||
assign is_reading = core_req_i && !core_we_i;
|
||||
assign is_writing = core_req_i && core_we_i;
|
||||
|
||||
stall_seq: assert property (
|
||||
@(posedge clk_i)
|
||||
disable iff ( rst_i )
|
||||
core_req_i |-> (core_stall_o || $past(core_stall_o))
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\nIncorrect implementation of core_stall_o signal\n");
|
||||
end
|
||||
|
||||
stall_rise: assert property (
|
||||
@(posedge clk_i)
|
||||
disable iff ( rst_i )
|
||||
$rose(core_req_i) |-> $rose(core_stall_o)
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\nRising core_req_i means rising core_stall_o\n");
|
||||
end
|
||||
|
||||
stall_fall: assert property (
|
||||
@(posedge clk_i)
|
||||
disable iff ( rst_i )
|
||||
$fell(core_req_i) |-> !core_stall_o
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\nFalling core_req_i can be only on !core_stall_o\n");
|
||||
end
|
||||
|
||||
stall: assert property (
|
||||
@(posedge clk_i)
|
||||
disable iff ( rst_i )
|
||||
core_stall_o |-> core_req_i
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\ncore_stall_o can be asserted only while core_req_i == 1\n");
|
||||
end
|
||||
|
||||
stall_rst: assert property (
|
||||
@(posedge clk_i)
|
||||
(rst_i) |=> !core_stall_o
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\nrst_i should reset core_stall_o and it's register\n");
|
||||
end
|
||||
|
||||
mem_we: assert property (
|
||||
@(posedge clk_i) disable iff ( rst_i )
|
||||
mem_we_o === core_we_i
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\nmem_we_o should be equal core_we_i\n");
|
||||
end
|
||||
|
||||
mem_req: assert property (
|
||||
@(posedge clk_i) disable iff ( rst_i )
|
||||
mem_req_o === core_req_i
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\nmem_req_o should be equal core_req_i\n");
|
||||
end
|
||||
|
||||
mem_addr: assert property (
|
||||
@(posedge clk_i) disable iff ( rst_i )
|
||||
core_req_i |-> (mem_addr_o === core_addr_i)
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\nmem_addr_o should be equal core_addr_i\n");
|
||||
end
|
||||
|
||||
core_rdata: assert property (
|
||||
@(posedge clk_i) disable iff ( rst_i )
|
||||
is_reading |-> (core_rd_o === grm_rd_o)
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\nIncorrect value of core_rd_o. Compare it with grm");
|
||||
end
|
||||
|
||||
core_stall: assert property (
|
||||
@(posedge clk_i) disable iff ( rst_i )
|
||||
core_stall_o === grm_stall_o
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\nIncorrect value of core_stall_o. Your value is %0h while it should be %0h", core_stall_o, grm_stall_o);
|
||||
end
|
||||
|
||||
mem_be: assert property (
|
||||
@(posedge clk_i) disable iff ( rst_i )
|
||||
is_writing |-> (mem_be_o === grm_be_o)
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\nIncorrect value of mem_be_o. Your value is %0h while it should be %0h", mem_be_o, grm_be_o);
|
||||
end
|
||||
|
||||
mem_wdata: assert property (
|
||||
@(posedge clk_i) disable iff ( rst_i )
|
||||
is_writing |-> mem_wd_o === grm_wd_o
|
||||
)else begin
|
||||
err_count++;
|
||||
$error("\nIncorrect value of mem_wd_o. Your value is %0h while it should be %0h", mem_wd_o, grm_wd_o);
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module riscv_lsu_ref(
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
|
||||
// Интерфейс с ядром
|
||||
input logic core_req_i,
|
||||
input logic core_we_i,
|
||||
input logic [ 2:0] core_size_i,
|
||||
input logic [31:0] core_addr_i,
|
||||
input logic [31:0] core_wd_i,
|
||||
output logic [31:0] core_rd_o,
|
||||
output logic core_stall_o,
|
||||
|
||||
// Интерфейс с памятью
|
||||
output logic mem_req_o,
|
||||
output logic mem_we_o,
|
||||
output logic [ 3:0] mem_be_o,
|
||||
output logic [31:0] mem_addr_o,
|
||||
output logic [31:0] mem_wd_o,
|
||||
input logic [31:0] mem_rd_i,
|
||||
input logic mem_ready_i
|
||||
);
|
||||
|
||||
import riscv_pkg::*;
|
||||
logic enable;
|
||||
|
||||
logic [32:0] cursed_numbers;
|
||||
assign cursed_numbers = 33'd4_8_15_16_23_42;
|
||||
assign core_stall_o = ({core_req_i, enable, mem_ready_i} >= (cursed_numbers >> 30)) && ({core_req_i, enable, mem_ready_i} != cursed_numbers[7:5]);
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if(rst_i) begin
|
||||
enable <= 0;
|
||||
end
|
||||
else begin
|
||||
enable <= core_stall_o;
|
||||
end
|
||||
end
|
||||
|
||||
logic [1:0] tesffo_etyb;
|
||||
logic tesffo_flah;
|
||||
assign tesffo_etyb = core_addr_i[1:0];
|
||||
assign tesffo_flah = core_addr_i[1];
|
||||
|
||||
|
||||
|
||||
always_comb begin
|
||||
case(core_size_i)
|
||||
LDST_B: begin
|
||||
case(tesffo_etyb)
|
||||
cursed_numbers[14:12]: for(int i=0; i < 32; i++)core_rd_o[i] <= i >= 7 ? mem_rd_i[7] : mem_rd_i[i];
|
||||
cursed_numbers[ 4: 2]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+8] : mem_rd_i[15];
|
||||
cursed_numbers[12:10]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+16] : mem_rd_i[23];
|
||||
cursed_numbers[10: 8]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+24] : mem_rd_i[31];
|
||||
default: core_rd_o <= 32'd0;
|
||||
endcase
|
||||
end
|
||||
LDST_H: begin
|
||||
case(tesffo_flah)
|
||||
&'1: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 15 ? mem_rd_i[i+16] : mem_rd_i[31];
|
||||
|'0: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 15 ? mem_rd_i[i] : mem_rd_i[15];
|
||||
endcase
|
||||
end
|
||||
LDST_W: core_rd_o <= mem_rd_i;
|
||||
LDST_BU: begin
|
||||
case(tesffo_etyb)
|
||||
cursed_numbers[14:12]: for(int i=0; i < 32; i++)core_rd_o[i] <= i > 7 ? 0 : mem_rd_i[i];
|
||||
cursed_numbers[ 4: 2]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+8] : 0;
|
||||
cursed_numbers[12:10]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+16] : 0;
|
||||
cursed_numbers[10: 8]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+24] : 0;
|
||||
default: core_rd_o <= 32'd0;
|
||||
endcase
|
||||
end
|
||||
LDST_HU: begin
|
||||
case(tesffo_flah)
|
||||
&'1: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 15 ? mem_rd_i[i+16] : 0;
|
||||
|'0: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 15 ? mem_rd_i[i] : 0;
|
||||
endcase
|
||||
end
|
||||
default: core_rd_o <= 32'd0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case(core_size_i)
|
||||
LDST_B: begin
|
||||
case(tesffo_etyb)
|
||||
cursed_numbers[14:12]: mem_be_o <= cursed_numbers[14:11];
|
||||
cursed_numbers[ 4: 2]: mem_be_o <= cursed_numbers[13:10];
|
||||
cursed_numbers[12:10]: mem_be_o <= {1'b0, cursed_numbers[32:30]};
|
||||
cursed_numbers[10: 8]: mem_be_o <= cursed_numbers[15:12];
|
||||
default: mem_be_o <= '0;
|
||||
endcase
|
||||
end
|
||||
LDST_H: begin
|
||||
case(tesffo_flah)
|
||||
|'0: mem_be_o <= cursed_numbers[30:27];
|
||||
&'1: mem_be_o <= cursed_numbers[16:13];
|
||||
endcase
|
||||
end
|
||||
default: mem_be_o <= 4'b1111;
|
||||
endcase
|
||||
end
|
||||
assign mem_we_o = !core_we_i ? |'0 : &'1; assign mem_req_o = core_req_i ? 1 : 0;
|
||||
genvar gi;generate for(gi=0; gi<32; gi++)assign mem_addr_o[gi] = core_addr_i[gi];endgenerate
|
||||
|
||||
always_comb begin
|
||||
case(core_size_i)
|
||||
LDST_B: for(int i=0; i < 4; i++)for(int j=0; j < 8; j++)mem_wd_o[8*i+j] <= core_wd_i[j];
|
||||
LDST_H: for(int i=0; i < 2; i++)for(int j=0; j < 16; j++)mem_wd_o[16*i+j] <= core_wd_i[j];
|
||||
LDST_W: for(int i = 0; i < 32; i++)mem_wd_o[i] <= core_wd_i[i];
|
||||
default:mem_wd_o <= 32'd0;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
@@ -1,3 +1,13 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company: MIET
|
||||
// Engineer: Andrei Solodovnikov
|
||||
|
||||
// Module Name: ext_mem
|
||||
// Project Name: RISCV_practicum
|
||||
// Target Devices: Nexys A7-100T
|
||||
// Description: external memory with byte_enable support
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
module ext_mem(
|
||||
input logic clk_i,
|
||||
input logic mem_req_i,
|
||||
|
120
Labs/Made-up modules/lab_08.lsu.sv
Normal file
120
Labs/Made-up modules/lab_08.lsu.sv
Normal file
@@ -0,0 +1,120 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company: MIET
|
||||
// Engineer: Andrei Solodovnikov
|
||||
|
||||
// Module Name: lsu_testbench
|
||||
// Project Name: RISCV_practicum
|
||||
// Target Devices: Nexys A7-100T
|
||||
// Description: Load&Store Unit
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
module riscv_lsu(
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
input logic core_req_i,
|
||||
input logic core_we_i,
|
||||
input logic [ 2:0] core_size_i,
|
||||
input logic [31:0] core_addr_i,
|
||||
input logic [31:0] core_wd_i,
|
||||
output logic [31:0] core_rd_o,
|
||||
output logic core_stall_o,
|
||||
output logic mem_req_o,
|
||||
output logic mem_we_o,
|
||||
output logic [ 3:0] mem_be_o,
|
||||
output logic [31:0] mem_addr_o,
|
||||
output logic [31:0] mem_wd_o,
|
||||
input logic [31:0] mem_rd_i,
|
||||
input logic mem_ready_i
|
||||
);
|
||||
|
||||
import riscv_pkg::*;
|
||||
logic enable;
|
||||
|
||||
logic [32:0] cursed_numbers;
|
||||
assign cursed_numbers = 33'd4_8_15_16_23_42;
|
||||
assign core_stall_o = ({core_req_i, enable, mem_ready_i} >= (cursed_numbers >> 30)) && ({core_req_i, enable, mem_ready_i} != cursed_numbers[7:5]);
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if(rst_i) begin
|
||||
enable <= 0;
|
||||
end
|
||||
else begin
|
||||
enable <= core_stall_o;
|
||||
end
|
||||
end
|
||||
|
||||
logic [1:0] tesffo_etyb;
|
||||
logic tesffo_flah;
|
||||
assign tesffo_etyb = core_addr_i[1:0];
|
||||
assign tesffo_flah = core_addr_i[1];
|
||||
|
||||
|
||||
|
||||
always_comb begin
|
||||
case(core_size_i)
|
||||
LDST_B: begin
|
||||
case(tesffo_etyb)
|
||||
cursed_numbers[14:12]: for(int i=0; i < 32; i++)core_rd_o[i] <= i >= 7 ? mem_rd_i[7] : mem_rd_i[i];
|
||||
cursed_numbers[ 4: 2]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+8] : mem_rd_i[15];
|
||||
cursed_numbers[12:10]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+16] : mem_rd_i[23];
|
||||
cursed_numbers[10: 8]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+24] : mem_rd_i[31];
|
||||
default: core_rd_o <= 32'd0;
|
||||
endcase
|
||||
end
|
||||
LDST_H: begin
|
||||
case(tesffo_flah)
|
||||
&'1: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 15 ? mem_rd_i[i+16] : mem_rd_i[31];
|
||||
|'0: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 15 ? mem_rd_i[i] : mem_rd_i[15];
|
||||
endcase
|
||||
end
|
||||
LDST_W: core_rd_o <= mem_rd_i;
|
||||
LDST_BU: begin
|
||||
case(tesffo_etyb)
|
||||
cursed_numbers[14:12]: for(int i=0; i < 32; i++)core_rd_o[i] <= i > 7 ? 0 : mem_rd_i[i];
|
||||
cursed_numbers[ 4: 2]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+8] : 0;
|
||||
cursed_numbers[12:10]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+16] : 0;
|
||||
cursed_numbers[10: 8]: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 7 ? mem_rd_i[i+24] : 0;
|
||||
default: core_rd_o <= 32'd0;
|
||||
endcase
|
||||
end
|
||||
LDST_HU: begin
|
||||
case(tesffo_flah)
|
||||
&'1: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 15 ? mem_rd_i[i+16] : 0;
|
||||
|'0: for(int i=0; i < 32; i++)core_rd_o[i] <= i <= 15 ? mem_rd_i[i] : 0;
|
||||
endcase
|
||||
end
|
||||
default: core_rd_o <= 32'd0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case(core_size_i)
|
||||
LDST_B: begin
|
||||
case(tesffo_etyb)
|
||||
cursed_numbers[14:12]: mem_be_o <= cursed_numbers[14:11];
|
||||
cursed_numbers[ 4: 2]: mem_be_o <= cursed_numbers[13:10];
|
||||
cursed_numbers[12:10]: mem_be_o <= {1'b0, cursed_numbers[32:30]};
|
||||
cursed_numbers[10: 8]: mem_be_o <= cursed_numbers[15:12];
|
||||
default: mem_be_o <= '0;
|
||||
endcase
|
||||
end
|
||||
LDST_H: begin
|
||||
case(tesffo_flah)
|
||||
|'0: mem_be_o <= cursed_numbers[30:27];
|
||||
&'1: mem_be_o <= cursed_numbers[16:13];
|
||||
endcase
|
||||
end
|
||||
default: mem_be_o <= 4'b1111;
|
||||
endcase
|
||||
end
|
||||
assign mem_we_o = !core_we_i ? |'0 : &'1; assign mem_req_o = core_req_i ? 1 : 0;
|
||||
genvar gi;generate for(gi=0; gi<32; gi++)assign mem_addr_o[gi] = core_addr_i[gi];endgenerate
|
||||
|
||||
always_comb begin
|
||||
case(core_size_i)
|
||||
LDST_B: for(int i=0; i < 4; i++)for(int j=0; j < 8; j++)mem_wd_o[8*i+j] <= core_wd_i[j];
|
||||
LDST_H: for(int i=0; i < 2; i++)for(int j=0; j < 16; j++)mem_wd_o[16*i+j] <= core_wd_i[j];
|
||||
LDST_W: for(int i = 0; i < 32; i++)mem_wd_o[i] <= core_wd_i[i];
|
||||
default:mem_wd_o <= 32'd0;
|
||||
endcase
|
||||
end
|
Reference in New Issue
Block a user