From b259d7f0845173e5419be70f97e9c1e629824caa Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Thu, 16 Nov 2023 18:28:48 -0800 Subject: [PATCH] Fix edge trigger, reorganize testbench --- .../simulation/tbs/interrupt_controller_tb.sv | 160 +++++++++--------- hw/efinix_fpga/src/interrupt_controller.sv | 6 +- 2 files changed, 85 insertions(+), 81 deletions(-) diff --git a/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv b/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv index 3276027..cee9f5a 100644 --- a/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv +++ b/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv @@ -34,72 +34,25 @@ interrupt_controller u_interrupt_controller( .int_out(int_out) ); -/* These should be shared */ -task write_reg(input logic [4:0] _addr, input logic [7:0] _data); - @(negedge r_clk_cpu); - cs <= '1; - addr <= _addr; - rwb <= '0; - i_data <= '1; - @(posedge r_clk_cpu); - i_data <= _data; - @(negedge r_clk_cpu); - cs <= '0; - rwb <= '1; -endtask - -task read_reg(input logic [2:0] _addr, output logic [7:0] _data); - @(negedge r_clk_cpu); - cs <= '1; - addr <= _addr; - rwb <= '1; - i_data <= '1; - @(posedge r_clk_cpu); - _data <= o_data; - @(negedge r_clk_cpu); - cs <= '0; - rwb <= '1; -endtask - /* Test Level triggered IRQ by triggering IRQ0 * and then clearing it, */ - // TODO this needs to test that it does not trigger after we clear the irq. task test_edge_irq(); $display("Testing Edge IRQ"); - repeat (5) @(posedge r_clk_cpu); - reset = 1; - cs = 0; - rwb = 1; - addr = '0; - i_data = '0; - int_in = '0; - repeat (5) @(posedge r_clk_cpu); - reset = 0; - repeat (5) @(posedge r_clk_cpu); - write_reg(0, 8'h10); // Enable register - write_reg(1, 8'hff); // 0-7 all enabled - write_reg(0, 8'h20); // Type register - write_reg(1, 8'h00); // 0-7 all level triggered? - repeat (5) @(posedge r_clk_cpu); - int_in = 1; - @(posedge r_clk_cpu) + do_reset(); + set_enable(255'hff); + set_edge_type(255'h0); + set_interrupts(1); assert (int_out == 1) else begin errors = errors + 1; $error("Interrupt should be high!"); end - repeat (5) @(posedge r_clk_cpu); - write_reg(0, 8'hff); - write_reg(1, 8'h01); - @(posedge r_clk_cpu); + send_eoi(); assert (int_out == 0) else begin errors = errors + 1; $error("Interrupt should be low!"); end - int_in = 0; - repeat (5) @(posedge r_clk_cpu); - write_reg(0, 8'hff); - write_reg(1, 8'h01); + set_interrupts(0); assert (int_out == 0) else begin errors = errors + 1; $error("Interrupt should be low!"); @@ -108,41 +61,21 @@ endtask task test_level_irq(); $display("Testing level IRQ"); - repeat (5) @(posedge r_clk_cpu); - reset = 1; - cs = 0; - rwb = 1; - addr = '0; - i_data = '0; - int_in = '0; - repeat (5) @(posedge r_clk_cpu); - reset = 0; - repeat (5) @(posedge r_clk_cpu); - write_reg(0, 8'h10); // Enable register - write_reg(1, 8'hff); // 0-7 all enabled - write_reg(0, 8'h20); // Type register - write_reg(1, 8'hff); // 0-7 all level triggered? - repeat (5) @(posedge r_clk_cpu); - int_in = 1; - @(posedge r_clk_cpu) + do_reset(); + set_enable(255'hff); + set_edge_type(255'hff); + set_interrupts(1); assert (int_out == 1) else begin errors = errors + 1; $error("Interrupt should be high!"); end - repeat (5) @(posedge r_clk_cpu); - write_reg(0, 8'hff); - write_reg(1, 8'h01); - @(posedge r_clk_cpu); + send_eoi(); assert (int_out == 1) else begin errors = errors + 1; $error("Interrupt should be high!"); end - int_in = 0; - repeat (5) @(posedge r_clk_cpu); - write_reg(0, 8'hff); - write_reg(1, 8'h01); - @(posedge r_clk_cpu); - repeat (5) @(posedge r_clk_cpu) + set_interrupts(0); + send_eoi(); assert (int_out == 0) else begin errors = errors + 1; $error("Interrupt should be low!"); @@ -167,4 +100,71 @@ begin $dumpvars(0,interrupt_controller_tb); end +/* These should be shared */ +task write_reg(input logic [4:0] _addr, input logic [7:0] _data); + @(negedge r_clk_cpu); + cs <= '1; + addr <= _addr; + rwb <= '0; + i_data <= '1; + @(posedge r_clk_cpu); + i_data <= _data; + @(negedge r_clk_cpu); + cs <= '0; + rwb <= '1; + @(posedge r_clk_cpu); +endtask + +task read_reg(input logic [2:0] _addr, output logic [7:0] _data); + @(negedge r_clk_cpu); + cs <= '1; + addr <= _addr; + rwb <= '1; + i_data <= '1; + @(posedge r_clk_cpu); + _data <= o_data; + @(negedge r_clk_cpu); + cs <= '0; + rwb <= '1; + @(posedge r_clk_cpu); +endtask + +task do_reset(); + repeat (5) @(posedge r_clk_cpu); + reset = 1; + cs = 0; + rwb = 1; + addr = '0; + i_data = '0; + int_in = '0; + repeat (5) @(posedge r_clk_cpu); + reset = 0; + repeat (5) @(posedge r_clk_cpu); +endtask + +task set_enable(input logic [255:0] en); + for (int i = 0; i < 16; i++) begin + write_reg(0, 8'h10 | 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 < 16; i++) begin + write_reg(0, 8'h20 | i); + write_reg(1, edge_type[8*i +: 8]); + end +endtask + +task set_interrupts(logic [255:0] ints); + int_in = ints; + @(posedge r_clk_cpu); +endtask + +task send_eoi(); + write_reg(0, 8'hff); + write_reg(1, 8'h01); +endtask + + endmodule diff --git a/hw/efinix_fpga/src/interrupt_controller.sv b/hw/efinix_fpga/src/interrupt_controller.sv index eee3aff..6d9a9e1 100644 --- a/hw/efinix_fpga/src/interrupt_controller.sv +++ b/hw/efinix_fpga/src/interrupt_controller.sv @@ -16,6 +16,8 @@ logic w_enable_write; logic [7:0] w_enable_data; logic [255:0] w_enable_full_data; +logic [255:0] int_in_d1; + logic [4:0] w_byte_sel; logic [7:0] irq_val; @@ -118,7 +120,7 @@ always_comb begin if (w_eoi && i == irq_val) begin r_int_next[i] = 0; end else begin - r_int_next[i] = (~r_int[i] & int_masked[i]) | r_int[i]; + r_int_next[i] = (~int_in_d1[i] & int_masked[i]) | r_int[i]; end end @@ -139,9 +141,11 @@ always_ff @(negedge clk) begin if (reset) begin r_int <= '0; cmd <= '0; + int_in_d1 <= '0; end else begin r_int <= r_int_next; cmd <= cmd_next; + int_in_d1 <= int_in; end end