diff --git a/hw/efinix_fpga/simulation/tbs/interrupt_controller_code_tb.sv b/hw/efinix_fpga/simulation/tbs/interrupt_controller_code_tb.sv index 791b6bc..a83a666 100644 --- a/hw/efinix_fpga/simulation/tbs/interrupt_controller_code_tb.sv +++ b/hw/efinix_fpga/simulation/tbs/interrupt_controller_code_tb.sv @@ -23,7 +23,7 @@ end initial begin // u_sim_top.u_dut.w_int_in = 0; repeat (2400) @(posedge u_sim_top.r_clk_cpu); - for (int i = 0; i < 256; i++) begin + for (int i = 0; i < 128; i++) begin repeat (100) @(posedge u_sim_top.r_clk_cpu); force u_sim_top.u_dut.u_interrupt_controller.int_in = 1 << i; $display("Activiating interrupt %d", i); diff --git a/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv b/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv index a234f5f..dd49a27 100644 --- a/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv +++ b/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv @@ -4,8 +4,7 @@ module interrupt_controller_tb(); logic r_clk_cpu; -localparam BITS_256 = 256'hffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; - +localparam BITS_128 = 128'hffffffffffffffffffffffffffffffff; // clk_cpu initial begin r_clk_cpu <= '1; @@ -21,10 +20,12 @@ logic [7:0] o_data; logic cs; logic rwb; -logic [255:0] int_in; +logic [127:0] int_in; logic int_out; -interrupt_controller u_interrupt_controller( +interrupt_controller #( + .N_INTERRUPTS(128) +) u_interrupt_controller ( .clk(r_clk_cpu), .reset(reset), .i_data(i_data), @@ -42,8 +43,8 @@ interrupt_controller u_interrupt_controller( task test_edge_irq(); $display("Testing Edge IRQ"); do_reset(); - set_enable(255'hff); - set_edge_type(255'h0); + set_enable(128'hff); + set_edge_type(128'h0); set_interrupts(1); assert (int_out == 1) else begin errors = errors + 1; @@ -64,8 +65,8 @@ endtask task test_level_irq(); $display("Testing level IRQ"); do_reset(); - set_enable(255'hff); - set_edge_type(255'hff); + set_enable(128'hff); + set_edge_type(128'hff); set_interrupts(1); assert (int_out == 1) else begin errors = errors + 1; @@ -91,8 +92,8 @@ task test_irq_val(); do_reset(); set_enable('1); set_edge_type('1); - for (int i = 255; i >= 0; i--) begin - set_interrupts(BITS_256 << i); + for (int i = 127; i >= 0; i--) begin + set_interrupts(BITS_128 << i); read_irqval(irq_val); assert(i == irq_val) else begin errors = errors + 1; @@ -100,8 +101,8 @@ task test_irq_val(); end end - for (int i = 0; i < 256; i++) begin - set_interrupts(BITS_256 >> i); + for (int i = 0; i < 128; i++) begin + set_interrupts(BITS_128 >> i); read_irqval(irq_val); assert(int_out == 1) else begin errors = errors + 1; @@ -175,21 +176,21 @@ task do_reset(); repeat (5) @(posedge r_clk_cpu); endtask -task set_enable(input logic [255:0] en); - for (int i = 0; i < 32; i++) begin +task set_enable(input logic [127:0] en); + for (int i = 0; i < 16; i++) begin write_reg(0, 8'h20 | i); write_reg(1, en[8*i +: 8]); end endtask -task set_edge_type(input logic [255:0] edge_type); - for (int i = 0; i < 32; i++) begin +task set_edge_type(input logic [127:0] edge_type); + for (int i = 0; i < 16; i++) begin write_reg(0, 8'h40 | i); write_reg(1, edge_type[8*i +: 8]); end endtask -task set_interrupts(logic [255:0] ints); +task set_interrupts(logic [127:0] ints); int_in = ints; @(posedge r_clk_cpu); endtask diff --git a/hw/efinix_fpga/src/interrupt_controller.sv b/hw/efinix_fpga/src/interrupt_controller.sv index 7f54f31..c556464 100644 --- a/hw/efinix_fpga/src/interrupt_controller.sv +++ b/hw/efinix_fpga/src/interrupt_controller.sv @@ -1,5 +1,7 @@ -module interrupt_controller -( +module interrupt_controller +#( + parameter N_INTERRUPTS = 128 +)( input clk, input reset, input [7:0] i_data, @@ -8,15 +10,15 @@ module interrupt_controller input cs, input rwb, - input [255:0] int_in, + input [N_INTERRUPTS-1:0] int_in, output logic int_out ); logic w_enable_write; logic [7:0] w_enable_data; -logic [255:0] w_enable_full_data; +logic [N_INTERRUPTS-1:0] w_enable_full_data; -logic [255:0] int_in_d1; +logic [N_INTERRUPTS-1:0] int_in_d1; logic [4:0] w_byte_sel; @@ -24,7 +26,7 @@ logic [7:0] irq_val; byte_sel_register #( .DATA_WIDTH(8), - .ADDR_WIDTH(32) + .ADDR_WIDTH(N_INTERRUPTS/8) ) reg_enable ( .i_clk(~clk), .i_reset(reset), @@ -40,17 +42,17 @@ logic we, re; assign we = cs & ~rwb; assign re = cs & rwb; -logic [255:0] int_masked; +logic [N_INTERRUPTS-1:0] int_masked; assign int_masked = int_in & w_enable_full_data; logic w_type_write; logic [7:0] w_type_data; -logic [255:0] w_type_full_data; +logic [N_INTERRUPTS-1:0] w_type_full_data; byte_sel_register #( .DATA_WIDTH(8), - .ADDR_WIDTH(32) + .ADDR_WIDTH(N_INTERRUPTS/8) ) reg_type ( .i_clk(~clk), .i_reset(reset), @@ -65,7 +67,7 @@ logic [7:0] cmd, cmd_next; logic w_eoi; -logic [255:0] r_int, r_int_next; +logic [N_INTERRUPTS-1:0] r_int, r_int_next; always_comb begin w_eoi = 0; @@ -108,13 +110,13 @@ always_comb begin int_out = |r_int; irq_val = 8'hff; - for (int i = 255; i >= 0; i--) begin + for (int i = N_INTERRUPTS-1; i >= 0; i--) begin if (r_int[i] == 1) begin irq_val = i; end end - for (int i = 0; i < 256; i++) begin + for (int i = 0; i < N_INTERRUPTS; i++) begin case (w_type_full_data[i]) 0: begin // Edge triggered if (w_eoi && i == irq_val) begin diff --git a/sw/kernel/devices/interrupt_controller.s b/sw/kernel/devices/interrupt_controller.s index 4c45167..a46c335 100644 --- a/sw/kernel/devices/interrupt_controller.s +++ b/sw/kernel/devices/interrupt_controller.s @@ -34,7 +34,7 @@ IRQ_CMD_EOI = $ff cmd_all: ; Send the same value to all 32 bytes txa - add #$20 + add #$10 sta tmp1 loop: txa @@ -51,12 +51,10 @@ loop: ; void enable_irq(uint8_t type, uint8_t irqnum); ; in A: .proc _enable_irq - ; Decide which byte we need to modify by dividing by 32 (>> 5) + ; Decide which byte we need to modify by dividing by 8 (>> 3) pha lsr lsr - lsr - lsr lsr ; A is now bytesel sta tmp2 ; tmp2 is now bytesel add #IRQ_CMD_ENABLE @@ -97,13 +95,12 @@ L3: sta IRQ_DAT_ADDR .endproc +; TODO this is mostly the same as enable, why copy? .proc _disable_irq ; Decide which byte we need to modify by dividing by 32 (>> 5) pha lsr lsr - lsr - lsr lsr ; A is now bytesel add #IRQ_CMD_ENABLE sta IRQ_CMD_ADDR diff --git a/sw/test_code/irq_test/main.s b/sw/test_code/irq_test/main.s index 7610350..31be63c 100644 --- a/sw/test_code/irq_test/main.s +++ b/sw/test_code/irq_test/main.s @@ -54,7 +54,7 @@ _init: cmd_all: txa - add #$20 + add #$10 sta tmp1 loop: txa