Added Pico Co-Processor Interface (PCPI)
This commit is contained in:
parent
d4331491a8
commit
0be990bd04
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
TEST_OBJS = $(addsuffix .o,$(basename $(wildcard tests/*.S)))
|
TEST_OBJS = $(addsuffix .o,$(basename $(wildcard tests/*.S)))
|
||||||
FIRMWARE_OBJS = firmware/start.o firmware/irq.o firmware/print.o firmware/sieve.o firmware/stats.o
|
FIRMWARE_OBJS = firmware/start.o firmware/irq.o firmware/print.o firmware/sieve.o firmware/multest.o firmware/stats.o
|
||||||
|
|
||||||
test: testbench.exe firmware/firmware.hex
|
test: testbench.exe firmware/firmware.hex
|
||||||
vvp -N testbench.exe
|
vvp -N testbench.exe
|
||||||
|
|
|
@ -16,6 +16,13 @@ void print_hex(unsigned int val);
|
||||||
// sieve.c
|
// sieve.c
|
||||||
void sieve();
|
void sieve();
|
||||||
|
|
||||||
|
// multest.c
|
||||||
|
uint32_t hard_mul(uint32_t a, uint32_t b);
|
||||||
|
uint32_t hard_mulh(uint32_t a, uint32_t b);
|
||||||
|
uint32_t hard_mulhsu(uint32_t a, uint32_t b);
|
||||||
|
uint32_t hard_mulhu(uint32_t a, uint32_t b);
|
||||||
|
void multest();
|
||||||
|
|
||||||
// stats.c
|
// stats.c
|
||||||
void stats();
|
void stats();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include "firmware.h"
|
||||||
|
|
||||||
|
uint32_t xorshift32() {
|
||||||
|
static uint32_t x = 314159265;
|
||||||
|
x ^= x << 13;
|
||||||
|
x ^= x >> 17;
|
||||||
|
x ^= x << 5;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void multest()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
uint32_t a = xorshift32();
|
||||||
|
uint32_t b = xorshift32();
|
||||||
|
|
||||||
|
uint64_t au = a, bu = b;
|
||||||
|
int64_t as = (int32_t)a, bs = (int32_t)b;
|
||||||
|
|
||||||
|
print_str("input [");
|
||||||
|
print_hex(as >> 32);
|
||||||
|
print_str("] ");
|
||||||
|
print_hex(a);
|
||||||
|
print_str(" [");
|
||||||
|
print_hex(bs >> 32);
|
||||||
|
print_str("] ");
|
||||||
|
print_hex(b);
|
||||||
|
print_chr('\n');
|
||||||
|
|
||||||
|
uint32_t h_mul, h_mulh, h_mulhsu, h_mulhu;
|
||||||
|
print_str("hard ");
|
||||||
|
|
||||||
|
h_mul = hard_mul(a, b);
|
||||||
|
print_hex(h_mul);
|
||||||
|
print_str(" ");
|
||||||
|
|
||||||
|
h_mulh = hard_mulh(a, b);
|
||||||
|
print_hex(h_mulh);
|
||||||
|
print_str(" ");
|
||||||
|
|
||||||
|
h_mulhsu = hard_mulhsu(a, b);
|
||||||
|
print_hex(h_mulhsu);
|
||||||
|
print_str(" ");
|
||||||
|
|
||||||
|
h_mulhu = hard_mulhu(a, b);
|
||||||
|
print_hex(h_mulhu);
|
||||||
|
print_chr('\n');
|
||||||
|
|
||||||
|
uint32_t s_mul, s_mulh, s_mulhsu, s_mulhu;
|
||||||
|
print_str("soft ");
|
||||||
|
|
||||||
|
s_mul = a * b;
|
||||||
|
print_hex(s_mul);
|
||||||
|
print_str(" ");
|
||||||
|
|
||||||
|
s_mulh = (as * bs) >> 32;
|
||||||
|
print_hex(s_mulh);
|
||||||
|
print_str(" ");
|
||||||
|
|
||||||
|
s_mulhsu = (as * bu) >> 32;
|
||||||
|
print_hex(s_mulhsu);
|
||||||
|
print_str(" ");
|
||||||
|
|
||||||
|
s_mulhu = (au * bu) >> 32;
|
||||||
|
print_hex(s_mulhu);
|
||||||
|
print_str(" ");
|
||||||
|
|
||||||
|
if (s_mul != h_mul || s_mulh != h_mulh || s_mulhsu != h_mulhsu || s_mulhu != h_mulhu) {
|
||||||
|
print_str("ERROR!\n");
|
||||||
|
asm volatile ("sbreak");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_str(" OK\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
.section .text
|
.section .text
|
||||||
.global irq
|
.global irq
|
||||||
.global sieve
|
.global sieve
|
||||||
|
.global multest
|
||||||
|
.global hard_mul
|
||||||
|
.global hard_mulh
|
||||||
|
.global hard_mulhsu
|
||||||
|
.global hard_mulhu
|
||||||
.global stats
|
.global stats
|
||||||
|
|
||||||
#define TEST(n) \
|
#define TEST(n) \
|
||||||
|
@ -220,6 +225,9 @@ start:
|
||||||
/* jump to sieve C code */
|
/* jump to sieve C code */
|
||||||
jal ra,sieve
|
jal ra,sieve
|
||||||
|
|
||||||
|
/* jump to sieve C code */
|
||||||
|
jal ra,multest
|
||||||
|
|
||||||
/* jump to stats C code */
|
/* jump to stats C code */
|
||||||
jal ra,stats
|
jal ra,stats
|
||||||
|
|
||||||
|
@ -239,3 +247,19 @@ start:
|
||||||
/* break */
|
/* break */
|
||||||
sbreak
|
sbreak
|
||||||
|
|
||||||
|
hard_mul:
|
||||||
|
mul a0, a0, a1
|
||||||
|
ret
|
||||||
|
|
||||||
|
hard_mulh:
|
||||||
|
mulh a0, a0, a1
|
||||||
|
ret
|
||||||
|
|
||||||
|
hard_mulhsu:
|
||||||
|
mulhsu a0, a0, a1
|
||||||
|
ret
|
||||||
|
|
||||||
|
hard_mulhu:
|
||||||
|
mulhu a0, a0, a1
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
197
picorv32.v
197
picorv32.v
|
@ -30,6 +30,7 @@ module picorv32 #(
|
||||||
parameter [ 0:0] ENABLE_REGS_16_31 = 1,
|
parameter [ 0:0] ENABLE_REGS_16_31 = 1,
|
||||||
parameter [ 0:0] ENABLE_REGS_DUALPORT = 1,
|
parameter [ 0:0] ENABLE_REGS_DUALPORT = 1,
|
||||||
parameter [ 0:0] LATCHED_MEM_RDATA = 0,
|
parameter [ 0:0] LATCHED_MEM_RDATA = 0,
|
||||||
|
parameter [ 0:0] ENABLE_PCPI = 0,
|
||||||
parameter [ 0:0] ENABLE_IRQ = 0,
|
parameter [ 0:0] ENABLE_IRQ = 0,
|
||||||
parameter [31:0] MASKED_IRQ = 32'h 0000_0000,
|
parameter [31:0] MASKED_IRQ = 32'h 0000_0000,
|
||||||
parameter [31:0] PROGADDR_RESET = 32'h 0000_0000,
|
parameter [31:0] PROGADDR_RESET = 32'h 0000_0000,
|
||||||
|
@ -47,14 +48,25 @@ module picorv32 #(
|
||||||
output reg [ 3:0] mem_wstrb,
|
output reg [ 3:0] mem_wstrb,
|
||||||
input [31:0] mem_rdata,
|
input [31:0] mem_rdata,
|
||||||
|
|
||||||
// look-ahead interface
|
// Look-Ahead Interface
|
||||||
output mem_la_read,
|
output mem_la_read,
|
||||||
output mem_la_write,
|
output mem_la_write,
|
||||||
output [31:0] mem_la_addr,
|
output [31:0] mem_la_addr,
|
||||||
output reg [31:0] mem_la_wdata,
|
output reg [31:0] mem_la_wdata,
|
||||||
output reg [ 3:0] mem_la_wstrb,
|
output reg [ 3:0] mem_la_wstrb,
|
||||||
|
|
||||||
// IRQ interface
|
// Pico Co-Processor Interface (PCPI)
|
||||||
|
output reg pcpi_insn_valid,
|
||||||
|
output reg [31:0] pcpi_insn,
|
||||||
|
output reg pcpi_rs1_valid,
|
||||||
|
output [31:0] pcpi_rs1,
|
||||||
|
output reg pcpi_rs2_valid,
|
||||||
|
output [31:0] pcpi_rs2,
|
||||||
|
input pcpi_rd_valid,
|
||||||
|
input [31:0] pcpi_rd,
|
||||||
|
input pcpi_ready,
|
||||||
|
|
||||||
|
// IRQ Interface
|
||||||
input [31:0] irq,
|
input [31:0] irq,
|
||||||
output reg [31:0] eoi
|
output reg [31:0] eoi
|
||||||
);
|
);
|
||||||
|
@ -71,6 +83,9 @@ module picorv32 #(
|
||||||
reg [31:0] cpuregs [0:regfile_size-1];
|
reg [31:0] cpuregs [0:regfile_size-1];
|
||||||
reg [4:0] reg_sh;
|
reg [4:0] reg_sh;
|
||||||
|
|
||||||
|
assign pcpi_rs1 = reg_op1;
|
||||||
|
assign pcpi_rs2 = reg_op2;
|
||||||
|
|
||||||
wire [31:0] next_pc;
|
wire [31:0] next_pc;
|
||||||
|
|
||||||
reg irq_active;
|
reg irq_active;
|
||||||
|
@ -318,6 +333,10 @@ module picorv32 #(
|
||||||
end
|
end
|
||||||
|
|
||||||
if (decoder_trigger && !decoder_pseudo_trigger) begin
|
if (decoder_trigger && !decoder_pseudo_trigger) begin
|
||||||
|
if (ENABLE_PCPI) begin
|
||||||
|
pcpi_insn <= mem_rdata_q;
|
||||||
|
end
|
||||||
|
|
||||||
instr_beq <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b000;
|
instr_beq <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b000;
|
||||||
instr_bne <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b001;
|
instr_bne <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b001;
|
||||||
instr_blt <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b100;
|
instr_blt <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b100;
|
||||||
|
@ -437,6 +456,9 @@ module picorv32 #(
|
||||||
reg [31:0] current_pc;
|
reg [31:0] current_pc;
|
||||||
assign next_pc = latched_store && latched_branch ? reg_out : reg_next_pc;
|
assign next_pc = latched_store && latched_branch ? reg_out : reg_next_pc;
|
||||||
|
|
||||||
|
reg [7:0] pcpi_timeout_counter;
|
||||||
|
reg pcpi_timeout;
|
||||||
|
|
||||||
reg [31:0] next_irq_pending;
|
reg [31:0] next_irq_pending;
|
||||||
reg do_waitirq;
|
reg do_waitirq;
|
||||||
|
|
||||||
|
@ -489,6 +511,15 @@ module picorv32 #(
|
||||||
|
|
||||||
reg_alu_out <= alu_out;
|
reg_alu_out <= alu_out;
|
||||||
|
|
||||||
|
if (ENABLE_PCPI) begin
|
||||||
|
if (pcpi_insn_valid) begin
|
||||||
|
if (pcpi_timeout_counter)
|
||||||
|
pcpi_timeout_counter <= pcpi_timeout_counter - 1;
|
||||||
|
end else
|
||||||
|
pcpi_timeout_counter <= ~0;
|
||||||
|
pcpi_timeout <= !pcpi_timeout_counter;
|
||||||
|
end
|
||||||
|
|
||||||
if (ENABLE_COUNTERS)
|
if (ENABLE_COUNTERS)
|
||||||
count_cycle <= resetn ? count_cycle + 1 : 0;
|
count_cycle <= resetn ? count_cycle + 1 : 0;
|
||||||
|
|
||||||
|
@ -520,6 +551,9 @@ module picorv32 #(
|
||||||
latched_is_lu <= 0;
|
latched_is_lu <= 0;
|
||||||
latched_is_lh <= 0;
|
latched_is_lh <= 0;
|
||||||
latched_is_lb <= 0;
|
latched_is_lb <= 0;
|
||||||
|
pcpi_insn_valid <= 0;
|
||||||
|
pcpi_rs1_valid <= 0;
|
||||||
|
pcpi_rs2_valid <= 0;
|
||||||
irq_active <= 0;
|
irq_active <= 0;
|
||||||
irq_mask <= ~0;
|
irq_mask <= ~0;
|
||||||
next_irq_pending = 0;
|
next_irq_pending = 0;
|
||||||
|
@ -567,6 +601,12 @@ module picorv32 #(
|
||||||
reg_pc <= current_pc;
|
reg_pc <= current_pc;
|
||||||
reg_next_pc <= current_pc;
|
reg_next_pc <= current_pc;
|
||||||
|
|
||||||
|
if (ENABLE_PCPI) begin
|
||||||
|
pcpi_insn_valid <= 0;
|
||||||
|
pcpi_rs1_valid <= 0;
|
||||||
|
pcpi_rs2_valid <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
latched_store <= 0;
|
latched_store <= 0;
|
||||||
latched_stalu <= 0;
|
latched_stalu <= 0;
|
||||||
latched_branch <= 0;
|
latched_branch <= 0;
|
||||||
|
@ -618,6 +658,20 @@ module picorv32 #(
|
||||||
$display("DECODE: 0x%08x %-0s", reg_pc, instruction ? instruction : "UNKNOWN");
|
$display("DECODE: 0x%08x %-0s", reg_pc, instruction ? instruction : "UNKNOWN");
|
||||||
`endif
|
`endif
|
||||||
if (instr_trap) begin
|
if (instr_trap) begin
|
||||||
|
if (ENABLE_PCPI) begin
|
||||||
|
pcpi_rs1_valid <= 1;
|
||||||
|
pcpi_insn_valid <= 1;
|
||||||
|
reg_op1 <= decoded_rs1 ? cpuregs[decoded_rs1] : 0;
|
||||||
|
if (ENABLE_REGS_DUALPORT) begin
|
||||||
|
pcpi_rs2_valid <= 1;
|
||||||
|
reg_sh <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
|
reg_op2 <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
|
if (pcpi_ready) begin
|
||||||
|
reg_out <= pcpi_rd;
|
||||||
|
latched_store <= pcpi_rd_valid;
|
||||||
|
cpu_state <= cpu_state_fetch;
|
||||||
|
end else
|
||||||
|
if (pcpi_timeout) begin
|
||||||
`ifdef DEBUG
|
`ifdef DEBUG
|
||||||
$display("SBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);
|
$display("SBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);
|
||||||
`endif
|
`endif
|
||||||
|
@ -626,6 +680,20 @@ module picorv32 #(
|
||||||
cpu_state <= cpu_state_fetch;
|
cpu_state <= cpu_state_fetch;
|
||||||
end else
|
end else
|
||||||
cpu_state <= cpu_state_trap;
|
cpu_state <= cpu_state_trap;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
cpu_state <= cpu_state_ld_rs2;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
`ifdef DEBUG
|
||||||
|
$display("SBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);
|
||||||
|
`endif
|
||||||
|
if (ENABLE_IRQ && !irq_mask[irq_sbreak] && !irq_active) begin
|
||||||
|
next_irq_pending[irq_sbreak] = 1;
|
||||||
|
cpu_state <= cpu_state_fetch;
|
||||||
|
end else
|
||||||
|
cpu_state <= cpu_state_trap;
|
||||||
|
end
|
||||||
end else
|
end else
|
||||||
if (is_rdcycle_rdcycleh_rdinstr_rdinstrh) begin
|
if (is_rdcycle_rdcycleh_rdinstr_rdinstrh) begin
|
||||||
(* parallel_case, full_case *)
|
(* parallel_case, full_case *)
|
||||||
|
@ -718,6 +786,24 @@ module picorv32 #(
|
||||||
`endif
|
`endif
|
||||||
reg_sh <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
reg_sh <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
reg_op2 <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
reg_op2 <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
|
if (ENABLE_PCPI && pcpi_insn_valid) begin
|
||||||
|
pcpi_rs2_valid <= 1;
|
||||||
|
if (pcpi_ready) begin
|
||||||
|
reg_out <= pcpi_rd;
|
||||||
|
latched_store <= pcpi_rd_valid;
|
||||||
|
cpu_state <= cpu_state_fetch;
|
||||||
|
end else
|
||||||
|
if (pcpi_timeout) begin
|
||||||
|
`ifdef DEBUG
|
||||||
|
$display("SBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);
|
||||||
|
`endif
|
||||||
|
if (ENABLE_IRQ && !irq_mask[irq_sbreak] && !irq_active) begin
|
||||||
|
next_irq_pending[irq_sbreak] = 1;
|
||||||
|
cpu_state <= cpu_state_fetch;
|
||||||
|
end else
|
||||||
|
cpu_state <= cpu_state_trap;
|
||||||
|
end
|
||||||
|
end else
|
||||||
if (is_sb_sh_sw) begin
|
if (is_sb_sh_sw) begin
|
||||||
cpu_state <= cpu_state_stmem;
|
cpu_state <= cpu_state_stmem;
|
||||||
mem_do_rinst <= 1;
|
mem_do_rinst <= 1;
|
||||||
|
@ -874,6 +960,70 @@ module picorv32 #(
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
* picorv32_pcpi_mul
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
|
module picorv32_pcpi_mul (
|
||||||
|
input clk, resetn,
|
||||||
|
|
||||||
|
input pcpi_insn_valid,
|
||||||
|
input [31:0] pcpi_insn,
|
||||||
|
input pcpi_rs1_valid,
|
||||||
|
input [31:0] pcpi_rs1,
|
||||||
|
input pcpi_rs2_valid,
|
||||||
|
input [31:0] pcpi_rs2,
|
||||||
|
output reg pcpi_rd_valid,
|
||||||
|
output reg [31:0] pcpi_rd,
|
||||||
|
output reg pcpi_ready
|
||||||
|
);
|
||||||
|
reg instr_mul, instr_mulh, instr_mulhsu, instr_mulhu;
|
||||||
|
wire instr_any_mul = |{instr_mul, instr_mulh, instr_mulhsu, instr_mulhu};
|
||||||
|
wire instr_any_mulh = |{instr_mulh, instr_mulhsu, instr_mulhu};
|
||||||
|
wire instr_rs1_signed = |{instr_mulh, instr_mulhsu};
|
||||||
|
wire instr_rs2_signed = |{instr_mulh};
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
instr_mul <= 0;
|
||||||
|
instr_mulh <= 0;
|
||||||
|
instr_mulhsu <= 0;
|
||||||
|
instr_mulhu <= 0;
|
||||||
|
|
||||||
|
if (pcpi_insn_valid && pcpi_insn[6:0] == 7'b0110011 && pcpi_insn[31:25] == 7'b0000001) begin
|
||||||
|
case (pcpi_insn[14:12])
|
||||||
|
3'b000: instr_mul <= 1;
|
||||||
|
3'b001: instr_mulh <= 1;
|
||||||
|
3'b010: instr_mulhsu <= 1;
|
||||||
|
3'b011: instr_mulhu <= 1;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// FIXME: This is just a behavioral model
|
||||||
|
|
||||||
|
reg [63:0] rs1, rs2;
|
||||||
|
always @(posedge clk) begin
|
||||||
|
pcpi_rd_valid <= 0;
|
||||||
|
pcpi_ready <= 0;
|
||||||
|
if (pcpi_rs1_valid && pcpi_rs2_valid && instr_any_mul) begin
|
||||||
|
if (instr_rs1_signed)
|
||||||
|
rs1 = $signed(pcpi_rs1);
|
||||||
|
else
|
||||||
|
rs1 = $unsigned(pcpi_rs1);
|
||||||
|
|
||||||
|
if (instr_rs2_signed)
|
||||||
|
rs2 = $signed(pcpi_rs2);
|
||||||
|
else
|
||||||
|
rs2 = $unsigned(pcpi_rs2);
|
||||||
|
|
||||||
|
pcpi_rd <= instr_any_mulh ? (rs1 * rs2) >> 32 : rs1 * rs2;
|
||||||
|
pcpi_rd_valid <= 1;
|
||||||
|
pcpi_ready <= 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
* picorv32_axi
|
* picorv32_axi
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
@ -882,6 +1032,7 @@ module picorv32_axi #(
|
||||||
parameter [ 0:0] ENABLE_COUNTERS = 1,
|
parameter [ 0:0] ENABLE_COUNTERS = 1,
|
||||||
parameter [ 0:0] ENABLE_REGS_16_31 = 1,
|
parameter [ 0:0] ENABLE_REGS_16_31 = 1,
|
||||||
parameter [ 0:0] ENABLE_REGS_DUALPORT = 1,
|
parameter [ 0:0] ENABLE_REGS_DUALPORT = 1,
|
||||||
|
parameter [ 0:0] ENABLE_MUL = 0,
|
||||||
parameter [ 0:0] ENABLE_IRQ = 0,
|
parameter [ 0:0] ENABLE_IRQ = 0,
|
||||||
parameter [31:0] MASKED_IRQ = 32'h 0000_0000,
|
parameter [31:0] MASKED_IRQ = 32'h 0000_0000,
|
||||||
parameter [31:0] PROGADDR_RESET = 32'h 0000_0000,
|
parameter [31:0] PROGADDR_RESET = 32'h 0000_0000,
|
||||||
|
@ -926,6 +1077,16 @@ module picorv32_axi #(
|
||||||
wire mem_ready;
|
wire mem_ready;
|
||||||
wire [31:0] mem_rdata;
|
wire [31:0] mem_rdata;
|
||||||
|
|
||||||
|
wire pcpi_insn_valid;
|
||||||
|
wire [31:0] pcpi_insn;
|
||||||
|
wire pcpi_rs1_valid;
|
||||||
|
wire [31:0] pcpi_rs1;
|
||||||
|
wire pcpi_rs2_valid;
|
||||||
|
wire [31:0] pcpi_rs2;
|
||||||
|
wire pcpi_rd_valid;
|
||||||
|
wire [31:0] pcpi_rd;
|
||||||
|
wire pcpi_ready;
|
||||||
|
|
||||||
picorv32_axi_adapter axi_adapter (
|
picorv32_axi_adapter axi_adapter (
|
||||||
.clk (clk ),
|
.clk (clk ),
|
||||||
.resetn (resetn ),
|
.resetn (resetn ),
|
||||||
|
@ -955,10 +1116,30 @@ module picorv32_axi #(
|
||||||
.mem_rdata (mem_rdata )
|
.mem_rdata (mem_rdata )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
generate if (ENABLE_MUL) begin
|
||||||
|
picorv32_pcpi_mul pcpi_mul (
|
||||||
|
.clk (clk ),
|
||||||
|
.resetn (resetn ),
|
||||||
|
.pcpi_insn_valid(pcpi_insn_valid),
|
||||||
|
.pcpi_insn (pcpi_insn ),
|
||||||
|
.pcpi_rs1_valid (pcpi_rs1_valid ),
|
||||||
|
.pcpi_rs1 (pcpi_rs1 ),
|
||||||
|
.pcpi_rs2_valid (pcpi_rs2_valid ),
|
||||||
|
.pcpi_rs2 (pcpi_rs2 ),
|
||||||
|
.pcpi_rd_valid (pcpi_rd_valid ),
|
||||||
|
.pcpi_rd (pcpi_rd ),
|
||||||
|
.pcpi_ready (pcpi_ready )
|
||||||
|
);
|
||||||
|
end else begin
|
||||||
|
assign pcpi_rd = 1'bx;
|
||||||
|
assign pcpi_ready = 0;
|
||||||
|
end endgenerate
|
||||||
|
|
||||||
picorv32 #(
|
picorv32 #(
|
||||||
.ENABLE_COUNTERS (ENABLE_COUNTERS ),
|
.ENABLE_COUNTERS (ENABLE_COUNTERS ),
|
||||||
.ENABLE_REGS_16_31 (ENABLE_REGS_16_31 ),
|
.ENABLE_REGS_16_31 (ENABLE_REGS_16_31 ),
|
||||||
.ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT),
|
.ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT),
|
||||||
|
.ENABLE_PCPI (ENABLE_MUL ),
|
||||||
.ENABLE_IRQ (ENABLE_IRQ ),
|
.ENABLE_IRQ (ENABLE_IRQ ),
|
||||||
.MASKED_IRQ (MASKED_IRQ ),
|
.MASKED_IRQ (MASKED_IRQ ),
|
||||||
.PROGADDR_RESET (PROGADDR_RESET ),
|
.PROGADDR_RESET (PROGADDR_RESET ),
|
||||||
|
@ -967,6 +1148,7 @@ module picorv32_axi #(
|
||||||
.clk (clk ),
|
.clk (clk ),
|
||||||
.resetn (resetn),
|
.resetn (resetn),
|
||||||
.trap (trap ),
|
.trap (trap ),
|
||||||
|
|
||||||
.mem_valid(mem_valid),
|
.mem_valid(mem_valid),
|
||||||
.mem_addr (mem_addr ),
|
.mem_addr (mem_addr ),
|
||||||
.mem_wdata(mem_wdata),
|
.mem_wdata(mem_wdata),
|
||||||
|
@ -974,6 +1156,17 @@ module picorv32_axi #(
|
||||||
.mem_instr(mem_instr),
|
.mem_instr(mem_instr),
|
||||||
.mem_ready(mem_ready),
|
.mem_ready(mem_ready),
|
||||||
.mem_rdata(mem_rdata),
|
.mem_rdata(mem_rdata),
|
||||||
|
|
||||||
|
.pcpi_insn_valid(pcpi_insn_valid),
|
||||||
|
.pcpi_insn (pcpi_insn ),
|
||||||
|
.pcpi_rs1_valid (pcpi_rs1_valid ),
|
||||||
|
.pcpi_rs1 (pcpi_rs1 ),
|
||||||
|
.pcpi_rs2_valid (pcpi_rs2_valid ),
|
||||||
|
.pcpi_rs2 (pcpi_rs2 ),
|
||||||
|
.pcpi_rd_valid (pcpi_rd_valid ),
|
||||||
|
.pcpi_rd (pcpi_rd ),
|
||||||
|
.pcpi_ready (pcpi_ready ),
|
||||||
|
|
||||||
.irq(irq),
|
.irq(irq),
|
||||||
.eoi(eoi)
|
.eoi(eoi)
|
||||||
);
|
);
|
||||||
|
|
|
@ -45,6 +45,7 @@ module testbench;
|
||||||
reg [31:0] mem_axi_rdata;
|
reg [31:0] mem_axi_rdata;
|
||||||
|
|
||||||
picorv32_axi #(
|
picorv32_axi #(
|
||||||
|
.ENABLE_MUL(1),
|
||||||
.ENABLE_IRQ(1)
|
.ENABLE_IRQ(1)
|
||||||
) uut (
|
) uut (
|
||||||
.clk (clk ),
|
.clk (clk ),
|
||||||
|
|
Loading…
Reference in New Issue