From e163e9461fc6bad0645c1703e7e800013c0ab88c Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 15 Nov 2023 18:46:18 -0800 Subject: [PATCH] Fix makefile, fix how interrupts are triggered --- hw/efinix_fpga/simulation/Makefile | 10 +++--- .../simulation/tbs/interrupt_controller_tb.sv | 32 +++++++++++++++---- hw/efinix_fpga/src/interrupt_controller.sv | 27 +++++++++++++--- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index bb818ae..2d6328d 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -9,7 +9,7 @@ TEST_PROGRAM_NAME?=loop_test TEST_FOLDER?=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME) TEST_PROGRAM?=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME)/$(TEST_PROGRAM_NAME).hex -STANDALONE_TB= interrupt_controller_tb mapper_code_tb +STANDALONE_TB= interrupt_controller_tb mapper_code_tb mapper_tb #TODO implement something like sources.list @@ -34,8 +34,8 @@ full_sim: $(TARGET) $(SD_IMAGE) $(STANDALONE_TB): $(SRCS) $(TBS) iverilog -g2005-sv $(FLAGS) -s $@ -o $@ $(INC) $(SRCS) $(TBS) -mapper_code_tb: $(SRCS) $(TBS) $(INIT_MEM) - iverilog -g2005-sv $(FLAGS) -s $@ -o $@ $(INC) $(SRCS) $(TBS) +# mapper_code_tb: $(SRCS) $(TBS) $(INIT_MEM) +# iverilog -g2005-sv $(FLAGS) -s $@ -o $@ $(INC) $(SRCS) $(TBS) $(TARGET): $(INIT_MEM) $(SRCS) @@ -57,5 +57,5 @@ clean: rm -rf $(TARGET) rm -rf $(INIT_MEM) rm -rf $(SD_IMAGE) - rm -rf mapper_tb - rm -rf mapper_tb.vcd + rm -rf $(STANDALONE_TB) + rm -rf *.vcd diff --git a/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv b/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv index b457ce2..08812e1 100644 --- a/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv +++ b/hw/efinix_fpga/simulation/tbs/interrupt_controller_tb.sv @@ -31,7 +31,7 @@ interrupt_controller u_interrupt_controller( .cs(cs), .rwb(rwb), .int_in(int_in), - .int_out(int_out2) + .int_out(int_out) ); /* These should be shared */ @@ -61,7 +61,11 @@ task read_reg(input logic [2:0] _addr, output logic [7:0] _data); rwb <= '1; endtask -initial begin +/* 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(); repeat (5) @(posedge r_clk_cpu); reset = 1; cs = 0; @@ -72,18 +76,32 @@ initial begin repeat (5) @(posedge r_clk_cpu); reset = 0; repeat (5) @(posedge r_clk_cpu); - write_reg(0, 8'h10); - write_reg(1, 8'hff); - write_reg(0, 8'h20); - write_reg(1, 8'hff); + 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) - int_in = 0; + assert (int_out == 1) else begin + $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); + assert (int_out == 0) else begin + $error("Interrupt should be low!"); + end + int_in = 0; repeat (5) @(posedge r_clk_cpu); + assert (int_out == 0) else begin + $error("Interrupt should be low!"); + end +endtask + +initial begin + test_edge_irq(); $finish(); end diff --git a/hw/efinix_fpga/src/interrupt_controller.sv b/hw/efinix_fpga/src/interrupt_controller.sv index 71b7885..25b7f82 100644 --- a/hw/efinix_fpga/src/interrupt_controller.sv +++ b/hw/efinix_fpga/src/interrupt_controller.sv @@ -24,7 +24,7 @@ byte_sel_register #( .DATA_WIDTH(8), .ADDR_WIDTH(32) ) reg_enable ( - .i_clk(clk), + .i_clk(~clk), .i_reset(reset), .i_write(w_enable_write), .i_byte_sel(w_byte_sel), @@ -50,7 +50,7 @@ byte_sel_register #( .DATA_WIDTH(8), .ADDR_WIDTH(32) ) reg_type ( - .i_clk(clk), + .i_clk(~clk), .i_reset(reset), .i_write(w_type_write), .i_byte_sel(w_byte_sel), @@ -112,9 +112,26 @@ always_comb begin end end - r_int_next = (~r_int | w_type_full_data) & int_masked | r_int; - if (w_eoi) begin - r_int_next[irq_val] = 0; + for (int i = 0; i < 256; i++) begin + case (w_type_full_data[i]) + 0: begin // Edge triggered + 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]; + end + end + + 1: begin // Level Triggered + // If we are trying to clear this interrupt but it is still active, + // then we don't actually want to clear it. + if (w_eoi && i == irq_val) begin + r_int_next[i] = int_masked[i]; + end else begin + r_int_next[i] = r_int[i]; + end + end + endcase end end