mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2025-03-12 18:16:55 -04:00
fpga: Add syscall interrupt
Add syscall interrupt to be used for syscalls. The interrupt is triggered by writing to an address in the 0xe1000000-0xe1ffffff The PicoRV32 core is configured to use its minimal, non RISCV-standard, interrupt implementation.
This commit is contained in:
parent
dd48b77047
commit
19ae709c81
@ -45,6 +45,8 @@ module tk1 #(
|
|||||||
output wire gpio3,
|
output wire gpio3,
|
||||||
output wire gpio4,
|
output wire gpio4,
|
||||||
|
|
||||||
|
input wire syscall,
|
||||||
|
|
||||||
input wire cs,
|
input wire cs,
|
||||||
input wire we,
|
input wire we,
|
||||||
input wire [ 7 : 0] address,
|
input wire [ 7 : 0] address,
|
||||||
@ -448,7 +450,17 @@ module tk1 #(
|
|||||||
end
|
end
|
||||||
|
|
||||||
// In unused space
|
// In unused space
|
||||||
if ((cpu_addr[29 : 24] > 6'h10) && (cpu_addr[29 : 24] < 6'h3f)) begin
|
if ((cpu_addr[29 : 24] > 6'h10) && (cpu_addr[29 : 24] < 6'h21)) begin
|
||||||
|
force_trap_set = 1'h1;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Outside SYSCALL
|
||||||
|
if (cpu_addr[29 : 24] == 6'h21 & |cpu_addr[23 : 2]) begin
|
||||||
|
force_trap_set = 1'h1;
|
||||||
|
end
|
||||||
|
|
||||||
|
// In unused space
|
||||||
|
if ((cpu_addr[29 : 24] > 6'h21) && (cpu_addr[29 : 24] < 6'h3f)) begin
|
||||||
force_trap_set = 1'h1;
|
force_trap_set = 1'h1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -878,6 +878,17 @@ module tb_tk1 ();
|
|||||||
// Unused trap range: 0xd1000000-0xfeffffff
|
// Unused trap range: 0xd1000000-0xfeffffff
|
||||||
$display("--- test11: Unused");
|
$display("--- test11: Unused");
|
||||||
cpu_read_check_range_should_trap(32'hd1000000, 32'hd100000f);
|
cpu_read_check_range_should_trap(32'hd1000000, 32'hd100000f);
|
||||||
|
cpu_read_check_range_should_trap(32'he0fffff0, 32'he0ffffff);
|
||||||
|
|
||||||
|
// SYSCALL trap range. 0xe1000004-0xe1ffffff
|
||||||
|
$display("--- test11: SYSCALL");
|
||||||
|
cpu_read_check_range_should_not_trap(32'he1000000, 32'he1000003);
|
||||||
|
cpu_read_check_range_should_trap(32'he1000004, 32'he100000f);
|
||||||
|
cpu_read_check_range_should_trap(32'he1fffff0, 32'he1ffffff);
|
||||||
|
|
||||||
|
// Unused trap range: 0xe2000000-0xfeffffff
|
||||||
|
$display("--- test11: Unused");
|
||||||
|
cpu_read_check_range_should_trap(32'he2000000, 32'he200000f);
|
||||||
cpu_read_check_range_should_trap(32'hfefffff0, 32'hfeffffff);
|
cpu_read_check_range_should_trap(32'hfefffff0, 32'hfeffffff);
|
||||||
|
|
||||||
// TK1 trap range: 0xff000400-0xffffffff
|
// TK1 trap range: 0xff000400-0xffffffff
|
||||||
|
@ -57,11 +57,13 @@ module application_fpga (
|
|||||||
localparam UART_PREFIX = 6'h03;
|
localparam UART_PREFIX = 6'h03;
|
||||||
localparam TOUCH_SENSE_PREFIX = 6'h04;
|
localparam TOUCH_SENSE_PREFIX = 6'h04;
|
||||||
localparam FW_RAM_PREFIX = 6'h10;
|
localparam FW_RAM_PREFIX = 6'h10;
|
||||||
|
localparam SYSCALL_PREFIX = 6'h21;
|
||||||
localparam TK1_PREFIX = 6'h3f;
|
localparam TK1_PREFIX = 6'h3f;
|
||||||
|
|
||||||
// Instruction used to cause a trap.
|
// Instruction used to cause a trap.
|
||||||
localparam ILLEGAL_INSTRUCTION = 32'h0;
|
localparam ILLEGAL_INSTRUCTION = 32'h0;
|
||||||
|
|
||||||
|
localparam IRQ31_IRQ_MASK = 2 ** 31;
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
// Registers, memories with associated wires.
|
// Registers, memories with associated wires.
|
||||||
@ -80,11 +82,13 @@ module application_fpga (
|
|||||||
wire reset_n;
|
wire reset_n;
|
||||||
|
|
||||||
/* verilator lint_off UNOPTFLAT */
|
/* verilator lint_off UNOPTFLAT */
|
||||||
|
reg [31 : 0] cpu_irq;
|
||||||
wire cpu_trap;
|
wire cpu_trap;
|
||||||
wire cpu_valid;
|
wire cpu_valid;
|
||||||
wire cpu_instr;
|
wire cpu_instr;
|
||||||
wire [03 : 0] cpu_wstrb;
|
wire [03 : 0] cpu_wstrb;
|
||||||
/* verilator lint_off UNUSED */
|
/* verilator lint_off UNUSED */
|
||||||
|
wire [31 : 0] cpu_eoi;
|
||||||
wire [31 : 0] cpu_addr;
|
wire [31 : 0] cpu_addr;
|
||||||
wire [31 : 0] cpu_wdata;
|
wire [31 : 0] cpu_wdata;
|
||||||
|
|
||||||
@ -139,6 +143,10 @@ module application_fpga (
|
|||||||
wire [31 : 0] touch_sense_read_data;
|
wire [31 : 0] touch_sense_read_data;
|
||||||
wire touch_sense_ready;
|
wire touch_sense_ready;
|
||||||
|
|
||||||
|
reg irq31_cs;
|
||||||
|
reg irq31_we;
|
||||||
|
reg irq31_eoi;
|
||||||
|
|
||||||
reg tk1_cs;
|
reg tk1_cs;
|
||||||
reg tk1_we;
|
reg tk1_we;
|
||||||
reg [ 7 : 0] tk1_address;
|
reg [ 7 : 0] tk1_address;
|
||||||
@ -166,12 +174,17 @@ module application_fpga (
|
|||||||
|
|
||||||
|
|
||||||
picorv32 #(
|
picorv32 #(
|
||||||
.ENABLE_COUNTERS(0),
|
.ENABLE_COUNTERS (0),
|
||||||
.TWO_STAGE_SHIFT(0),
|
.TWO_STAGE_SHIFT (0),
|
||||||
.CATCH_MISALIGN (0),
|
.CATCH_MISALIGN (0),
|
||||||
.COMPRESSED_ISA (1),
|
.COMPRESSED_ISA (1),
|
||||||
.ENABLE_FAST_MUL(1),
|
.ENABLE_FAST_MUL (1),
|
||||||
.BARREL_SHIFTER (1)
|
.BARREL_SHIFTER (1),
|
||||||
|
.ENABLE_IRQ (1),
|
||||||
|
.ENABLE_IRQ_QREGS(0),
|
||||||
|
.ENABLE_IRQ_TIMER(0),
|
||||||
|
.MASKED_IRQ (~IRQ31_IRQ_MASK),
|
||||||
|
.LATCHED_IRQ (IRQ31_IRQ_MASK)
|
||||||
) cpu (
|
) cpu (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.resetn(reset_n),
|
.resetn(reset_n),
|
||||||
@ -185,11 +198,12 @@ module application_fpga (
|
|||||||
.mem_rdata(muxed_rdata_reg),
|
.mem_rdata(muxed_rdata_reg),
|
||||||
.mem_instr(cpu_instr),
|
.mem_instr(cpu_instr),
|
||||||
|
|
||||||
|
.irq(cpu_irq),
|
||||||
|
.eoi(cpu_eoi),
|
||||||
|
|
||||||
// Defined unused ports. Makes lint happy. But
|
// Defined unused ports. Makes lint happy. But
|
||||||
// we still needs to help lint with empty ports.
|
// we still needs to help lint with empty ports.
|
||||||
/* verilator lint_off PINCONNECTEMPTY */
|
/* verilator lint_off PINCONNECTEMPTY */
|
||||||
.irq(32'h0),
|
|
||||||
.eoi(),
|
|
||||||
.trace_valid(),
|
.trace_valid(),
|
||||||
.trace_data(),
|
.trace_data(),
|
||||||
.mem_la_read(),
|
.mem_la_read(),
|
||||||
@ -353,6 +367,8 @@ module application_fpga (
|
|||||||
.gpio3(app_gpio3),
|
.gpio3(app_gpio3),
|
||||||
.gpio4(app_gpio4),
|
.gpio4(app_gpio4),
|
||||||
|
|
||||||
|
.syscall(irq31_eoi),
|
||||||
|
|
||||||
.cs(tk1_cs),
|
.cs(tk1_cs),
|
||||||
.we(tk1_we),
|
.we(tk1_we),
|
||||||
.address(tk1_address),
|
.address(tk1_address),
|
||||||
@ -379,6 +395,20 @@ module application_fpga (
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
// irq_ctrl
|
||||||
|
// Interrupt logic
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
always @* begin : irq_ctrl
|
||||||
|
reg irq31_set;
|
||||||
|
|
||||||
|
irq31_set = irq31_cs & irq31_we;
|
||||||
|
cpu_irq = {irq31_set, 31'h0};
|
||||||
|
|
||||||
|
irq31_eoi = cpu_eoi[31];
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
// cpu_mem_ctrl
|
// cpu_mem_ctrl
|
||||||
// CPU memory decode and control logic.
|
// CPU memory decode and control logic.
|
||||||
@ -428,6 +458,9 @@ module application_fpga (
|
|||||||
touch_sense_we = |cpu_wstrb;
|
touch_sense_we = |cpu_wstrb;
|
||||||
touch_sense_address = cpu_addr[9 : 2];
|
touch_sense_address = cpu_addr[9 : 2];
|
||||||
|
|
||||||
|
irq31_cs = 1'h0;
|
||||||
|
irq31_we = |cpu_wstrb;
|
||||||
|
|
||||||
tk1_cs = 1'h0;
|
tk1_cs = 1'h0;
|
||||||
tk1_we = |cpu_wstrb;
|
tk1_we = |cpu_wstrb;
|
||||||
tk1_address = cpu_addr[9 : 2];
|
tk1_address = cpu_addr[9 : 2];
|
||||||
@ -500,6 +533,11 @@ module application_fpga (
|
|||||||
muxed_ready_new = fw_ram_ready;
|
muxed_ready_new = fw_ram_ready;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SYSCALL_PREFIX: begin
|
||||||
|
irq31_cs = 1'h1;
|
||||||
|
muxed_ready_new = 1'h1;
|
||||||
|
end
|
||||||
|
|
||||||
TK1_PREFIX: begin
|
TK1_PREFIX: begin
|
||||||
tk1_cs = 1'h1;
|
tk1_cs = 1'h1;
|
||||||
muxed_rdata_new = tk1_read_data;
|
muxed_rdata_new = tk1_read_data;
|
||||||
|
@ -70,11 +70,13 @@ module application_fpga_sim (
|
|||||||
localparam UART_PREFIX = 6'h03;
|
localparam UART_PREFIX = 6'h03;
|
||||||
localparam TOUCH_SENSE_PREFIX = 6'h04;
|
localparam TOUCH_SENSE_PREFIX = 6'h04;
|
||||||
localparam FW_RAM_PREFIX = 6'h10;
|
localparam FW_RAM_PREFIX = 6'h10;
|
||||||
|
localparam SYSCALL_PREFIX = 6'h21;
|
||||||
localparam TK1_PREFIX = 6'h3f;
|
localparam TK1_PREFIX = 6'h3f;
|
||||||
|
|
||||||
// Instruction used to cause a trap.
|
// Instruction used to cause a trap.
|
||||||
localparam ILLEGAL_INSTRUCTION = 32'h0;
|
localparam ILLEGAL_INSTRUCTION = 32'h0;
|
||||||
|
|
||||||
|
localparam IRQ31_IRQ_MASK = 2 ** 31;
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
// Registers, memories with associated wires.
|
// Registers, memories with associated wires.
|
||||||
@ -92,11 +94,13 @@ module application_fpga_sim (
|
|||||||
wire reset_n;
|
wire reset_n;
|
||||||
|
|
||||||
/* verilator lint_off UNOPTFLAT */
|
/* verilator lint_off UNOPTFLAT */
|
||||||
|
reg [31 : 0] cpu_irq;
|
||||||
wire cpu_trap;
|
wire cpu_trap;
|
||||||
wire cpu_valid;
|
wire cpu_valid;
|
||||||
wire cpu_instr;
|
wire cpu_instr;
|
||||||
wire [ 3 : 0] cpu_wstrb;
|
wire [ 3 : 0] cpu_wstrb;
|
||||||
/* verilator lint_off UNUSED */
|
/* verilator lint_off UNUSED */
|
||||||
|
wire [31 : 0] cpu_eoi;
|
||||||
wire [31 : 0] cpu_addr;
|
wire [31 : 0] cpu_addr;
|
||||||
wire [31 : 0] cpu_wdata;
|
wire [31 : 0] cpu_wdata;
|
||||||
|
|
||||||
@ -151,6 +155,10 @@ module application_fpga_sim (
|
|||||||
wire [31 : 0] touch_sense_read_data;
|
wire [31 : 0] touch_sense_read_data;
|
||||||
wire touch_sense_ready;
|
wire touch_sense_ready;
|
||||||
|
|
||||||
|
reg irq31_cs;
|
||||||
|
reg irq31_we;
|
||||||
|
reg irq31_eoi;
|
||||||
|
|
||||||
reg tk1_cs;
|
reg tk1_cs;
|
||||||
reg tk1_we;
|
reg tk1_we;
|
||||||
reg [ 7 : 0] tk1_address;
|
reg [ 7 : 0] tk1_address;
|
||||||
@ -177,12 +185,17 @@ module application_fpga_sim (
|
|||||||
|
|
||||||
|
|
||||||
picorv32 #(
|
picorv32 #(
|
||||||
.ENABLE_COUNTERS(0),
|
.ENABLE_COUNTERS (0),
|
||||||
.TWO_STAGE_SHIFT(0),
|
.TWO_STAGE_SHIFT (0),
|
||||||
.CATCH_MISALIGN (0),
|
.CATCH_MISALIGN (0),
|
||||||
.COMPRESSED_ISA (1),
|
.COMPRESSED_ISA (1),
|
||||||
.ENABLE_FAST_MUL(1),
|
.ENABLE_FAST_MUL (1),
|
||||||
.BARREL_SHIFTER (1)
|
.BARREL_SHIFTER (1),
|
||||||
|
.ENABLE_IRQ (1),
|
||||||
|
.ENABLE_IRQ_QREGS(0),
|
||||||
|
.ENABLE_IRQ_TIMER(0),
|
||||||
|
.MASKED_IRQ (~IRQ31_IRQ_MASK),
|
||||||
|
.LATCHED_IRQ (IRQ31_IRQ_MASK)
|
||||||
) cpu (
|
) cpu (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.resetn(reset_n),
|
.resetn(reset_n),
|
||||||
@ -196,11 +209,12 @@ module application_fpga_sim (
|
|||||||
.mem_rdata(muxed_rdata_reg),
|
.mem_rdata(muxed_rdata_reg),
|
||||||
.mem_instr(cpu_instr),
|
.mem_instr(cpu_instr),
|
||||||
|
|
||||||
|
.irq(cpu_irq),
|
||||||
|
.eoi(cpu_eoi),
|
||||||
|
|
||||||
// Defined unused ports. Makes lint happy. But
|
// Defined unused ports. Makes lint happy. But
|
||||||
// we still needs to help lint with empty ports.
|
// we still needs to help lint with empty ports.
|
||||||
/* verilator lint_off PINCONNECTEMPTY */
|
/* verilator lint_off PINCONNECTEMPTY */
|
||||||
.irq(32'h0),
|
|
||||||
.eoi(),
|
|
||||||
.trace_valid(),
|
.trace_valid(),
|
||||||
.trace_data(),
|
.trace_data(),
|
||||||
.mem_la_read(),
|
.mem_la_read(),
|
||||||
@ -366,6 +380,8 @@ module application_fpga_sim (
|
|||||||
.gpio3(app_gpio3),
|
.gpio3(app_gpio3),
|
||||||
.gpio4(app_gpio4),
|
.gpio4(app_gpio4),
|
||||||
|
|
||||||
|
.syscall(irq31_eoi),
|
||||||
|
|
||||||
.cs(tk1_cs),
|
.cs(tk1_cs),
|
||||||
.we(tk1_we),
|
.we(tk1_we),
|
||||||
.address(tk1_address),
|
.address(tk1_address),
|
||||||
@ -391,6 +407,20 @@ module application_fpga_sim (
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
// irq_ctrl
|
||||||
|
// Interrupt logic
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
always @* begin : irq_ctrl
|
||||||
|
reg irq31_set;
|
||||||
|
|
||||||
|
irq31_set = irq31_cs & irq31_we;
|
||||||
|
cpu_irq = {irq31_set, 31'h0};
|
||||||
|
|
||||||
|
irq31_eoi = cpu_eoi[31];
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
// cpu_mem_ctrl
|
// cpu_mem_ctrl
|
||||||
// CPU memory decode and control logic.
|
// CPU memory decode and control logic.
|
||||||
@ -442,6 +472,9 @@ module application_fpga_sim (
|
|||||||
touch_sense_we = |cpu_wstrb;
|
touch_sense_we = |cpu_wstrb;
|
||||||
touch_sense_address = cpu_addr[9 : 2];
|
touch_sense_address = cpu_addr[9 : 2];
|
||||||
|
|
||||||
|
irq31_cs = 1'h0;
|
||||||
|
irq31_we = |cpu_wstrb;
|
||||||
|
|
||||||
tk1_cs = 1'h0;
|
tk1_cs = 1'h0;
|
||||||
tk1_we = |cpu_wstrb;
|
tk1_we = |cpu_wstrb;
|
||||||
tk1_address = cpu_addr[9 : 2];
|
tk1_address = cpu_addr[9 : 2];
|
||||||
@ -534,6 +567,13 @@ module application_fpga_sim (
|
|||||||
muxed_ready_new = fw_ram_ready;
|
muxed_ready_new = fw_ram_ready;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SYSCALL_PREFIX: begin
|
||||||
|
`verbose($display("Access to syscall interrupt trigger");)
|
||||||
|
ascii_state = "Syscall IRQ trigger";
|
||||||
|
irq31_cs = 1'h1;
|
||||||
|
muxed_ready_new = 1'h1;
|
||||||
|
end
|
||||||
|
|
||||||
TK1_PREFIX: begin
|
TK1_PREFIX: begin
|
||||||
`verbose($display("Access to TK1 core");)
|
`verbose($display("Access to TK1 core");)
|
||||||
ascii_state = "TK1 core";
|
ascii_state = "TK1 core";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user