diff --git a/hw/efinix_fpga/debug_profile.wizard.json b/hw/efinix_fpga/debug_profile.wizard.json index 6a81375..f56ca80 100644 --- a/hw/efinix_fpga/debug_profile.wizard.json +++ b/hw/efinix_fpga/debug_profile.wizard.json @@ -3,7 +3,7 @@ { "name": "la0", "type": "la", - "uuid": "0783f8a7edf7498d8f9e6d19f8bd60d1", + "uuid": "24a3c49eea4a40a18b701e64e40b6ba0", "trigin_en": false, "trigout_en": false, "auto_inserted": true, diff --git a/hw/efinix_fpga/interrupt_controller.sv b/hw/efinix_fpga/interrupt_controller.sv new file mode 100644 index 0000000..4e00957 --- /dev/null +++ b/hw/efinix_fpga/interrupt_controller.sv @@ -0,0 +1,30 @@ +module interrupt_controller +( + input clk, + input reset, + input [7:0] i_data, + output logic [7:0] o_data, + input cs, + input rwb, + + output logic irqb_master, + + input irqb0, irqb1, irqb2, irqb3, + input irqb4, irqb5, irqb6, irqb7 +); + + +//All of the inputs are low level triggered. +logic [7:0] irqbv; +assign irqbv = {irqb0, irqb1, irqb2, irqb3, irqb4, irqb5, irqb6, irqb7}; + +always @(posedge clk) begin + o_data <= irqbv; + irqb_master = &irqbv; + + if (cs & ~rwb) begin + o_data <= o_data | i_data; + end +end + +endmodule \ No newline at end of file diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile new file mode 100644 index 0000000..2befbaf --- /dev/null +++ b/hw/efinix_fpga/simulation/Makefile @@ -0,0 +1,17 @@ +TARGETS= timer interrupt_controller +TB=$(patsubst %, %_tb.sv, $(TARGETS)) + +all: $(TARGETS) + +timer: timer_tb.sv + iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv + +interrupt_controller: interrupt_controller_tb.sv + iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv + +.PHONY: clean + +clean: + rm -f $(TARGETS) + rm -f *.vcd + rm -f *.vvp \ No newline at end of file diff --git a/hw/efinix_fpga/simulation/interrupt_controller_tb.sv b/hw/efinix_fpga/simulation/interrupt_controller_tb.sv new file mode 100644 index 0000000..7cd41e8 --- /dev/null +++ b/hw/efinix_fpga/simulation/interrupt_controller_tb.sv @@ -0,0 +1,76 @@ +module sim(); + +timeunit 10ns; +timeprecision 1ns; + +logic clk; +logic reset; +logic [2:0] addr; +logic [7:0] i_data; +logic [7:0] o_data; +logic cs; +logic rwb; + +logic irqb_master; +logic irqb0, irqb1, irqb2, irqb3, irqb4, irqb5, irqb6, irqb7; + +interrupt_controller dut( + .*); + +always #100 clk = clk === 1'b0; + +task write_reg(input logic [2:0] _addr, input logic [7:0] _data); + @(negedge clk); + cs <= '1; + addr <= _addr; + rwb <= '0; + i_data <= '1; + @(posedge clk); + i_data <= _data; + @(negedge clk); + cs <= '0; + rwb <= '1; +endtask + +task read_reg(input logic [2:0] _addr, output logic [7:0] _data); + @(negedge clk); + cs <= '1; + addr <= _addr; + rwb <= '1; + i_data <= '1; + @(posedge clk); + _data <= o_data; + @(negedge clk); + cs <= '0; + rwb <= '1; +endtask + +initial +begin + $dumpfile("interrupt_controller.vcd"); + $dumpvars(0,sim); +end + +initial begin + reset <= '1; + irqb0 <= '1; + irqb1 <= '1; + irqb2 <= '1; + irqb3 <= '1; + irqb4 <= '1; + irqb5 <= '1; + irqb6 <= '1; + irqb7 <= '1; + repeat(5) @(posedge clk); + reset <= '0; + + repeat(5) @(posedge clk); + + irqb0 <= '0; + + repeat(5) @(posedge clk); + + $finish(); +end + +endmodule diff --git a/hw/efinix_fpga/super6502.sv b/hw/efinix_fpga/super6502.sv index bfcb4fa..daf4ce5 100644 --- a/hw/efinix_fpga/super6502.sv +++ b/hw/efinix_fpga/super6502.sv @@ -44,7 +44,6 @@ assign o_pll_reset = '1; assign cpu_data_oe = {8{cpu_rwb}}; assign cpu_rdy = '1; -assign cpu_irqb = '1; assign cpu_nmib = '1; assign cpu_phi2 = clk_2; @@ -115,6 +114,8 @@ leds u_leds( .o_leds(leds) ); +logic w_timer_irq; + timer u_timer( .clk(clk_2), .reset(~cpu_resb), @@ -122,7 +123,8 @@ timer u_timer( .o_data(w_timer_data_out), .cs(w_timer_cs), .rwb(cpu_rwb), - .addr(cpu_addr[2:0]) + .addr(cpu_addr[2:0]), + .irq(w_timer_irq) ); sdram_adapter u_sdram_adapter( @@ -154,5 +156,23 @@ sdram_adapter u_sdram_adapter( .o_sdr_DQM(o_sdr_DQM) ); +interrupt_controller u_interrupt_controller( + .clk(clk_2), + .reset(~cpu_resb), + .i_data(cpu_data_in), + .o_data(w_irq_data_out), + .cs(w_irq_cs), + .rwb(cpu_rwb), + .irqb_master(cpu_irqb), + .irqb0(w_timer_irq), + .irqb1('1), + .irqb2('1), + .irqb3('1), + .irqb4('1), + .irqb5('1), + .irqb6('1), + .irqb7('1) +); + endmodule diff --git a/hw/efinix_fpga/super6502.xml b/hw/efinix_fpga/super6502.xml index d62979b..73524f1 100644 --- a/hw/efinix_fpga/super6502.xml +++ b/hw/efinix_fpga/super6502.xml @@ -1,5 +1,5 @@ - + @@ -17,6 +17,7 @@ +