#53 Reduce interrupts to 128

This commit is contained in:
Byron Lathi
2023-11-21 08:17:36 -08:00
parent e7f8be44b7
commit 4392a01de8
5 changed files with 37 additions and 37 deletions

View File

@@ -23,7 +23,7 @@ end
initial begin initial begin
// u_sim_top.u_dut.w_int_in = 0; // u_sim_top.u_dut.w_int_in = 0;
repeat (2400) @(posedge u_sim_top.r_clk_cpu); 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); repeat (100) @(posedge u_sim_top.r_clk_cpu);
force u_sim_top.u_dut.u_interrupt_controller.int_in = 1 << i; force u_sim_top.u_dut.u_interrupt_controller.int_in = 1 << i;
$display("Activiating interrupt %d", i); $display("Activiating interrupt %d", i);

View File

@@ -4,8 +4,7 @@ module interrupt_controller_tb();
logic r_clk_cpu; logic r_clk_cpu;
localparam BITS_256 = 256'hffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; localparam BITS_128 = 128'hffffffffffffffffffffffffffffffff;
// clk_cpu // clk_cpu
initial begin initial begin
r_clk_cpu <= '1; r_clk_cpu <= '1;
@@ -21,10 +20,12 @@ logic [7:0] o_data;
logic cs; logic cs;
logic rwb; logic rwb;
logic [255:0] int_in; logic [127:0] int_in;
logic int_out; logic int_out;
interrupt_controller u_interrupt_controller( interrupt_controller #(
.N_INTERRUPTS(128)
) u_interrupt_controller (
.clk(r_clk_cpu), .clk(r_clk_cpu),
.reset(reset), .reset(reset),
.i_data(i_data), .i_data(i_data),
@@ -42,8 +43,8 @@ interrupt_controller u_interrupt_controller(
task test_edge_irq(); task test_edge_irq();
$display("Testing Edge IRQ"); $display("Testing Edge IRQ");
do_reset(); do_reset();
set_enable(255'hff); set_enable(128'hff);
set_edge_type(255'h0); set_edge_type(128'h0);
set_interrupts(1); set_interrupts(1);
assert (int_out == 1) else begin assert (int_out == 1) else begin
errors = errors + 1; errors = errors + 1;
@@ -64,8 +65,8 @@ endtask
task test_level_irq(); task test_level_irq();
$display("Testing level IRQ"); $display("Testing level IRQ");
do_reset(); do_reset();
set_enable(255'hff); set_enable(128'hff);
set_edge_type(255'hff); set_edge_type(128'hff);
set_interrupts(1); set_interrupts(1);
assert (int_out == 1) else begin assert (int_out == 1) else begin
errors = errors + 1; errors = errors + 1;
@@ -91,8 +92,8 @@ task test_irq_val();
do_reset(); do_reset();
set_enable('1); set_enable('1);
set_edge_type('1); set_edge_type('1);
for (int i = 255; i >= 0; i--) begin for (int i = 127; i >= 0; i--) begin
set_interrupts(BITS_256 << i); set_interrupts(BITS_128 << i);
read_irqval(irq_val); read_irqval(irq_val);
assert(i == irq_val) else begin assert(i == irq_val) else begin
errors = errors + 1; errors = errors + 1;
@@ -100,8 +101,8 @@ task test_irq_val();
end end
end end
for (int i = 0; i < 256; i++) begin for (int i = 0; i < 128; i++) begin
set_interrupts(BITS_256 >> i); set_interrupts(BITS_128 >> i);
read_irqval(irq_val); read_irqval(irq_val);
assert(int_out == 1) else begin assert(int_out == 1) else begin
errors = errors + 1; errors = errors + 1;
@@ -175,21 +176,21 @@ task do_reset();
repeat (5) @(posedge r_clk_cpu); repeat (5) @(posedge r_clk_cpu);
endtask endtask
task set_enable(input logic [255:0] en); task set_enable(input logic [127:0] en);
for (int i = 0; i < 32; i++) begin for (int i = 0; i < 16; i++) begin
write_reg(0, 8'h20 | i); write_reg(0, 8'h20 | i);
write_reg(1, en[8*i +: 8]); write_reg(1, en[8*i +: 8]);
end end
endtask endtask
task set_edge_type(input logic [255:0] edge_type); task set_edge_type(input logic [127:0] edge_type);
for (int i = 0; i < 32; i++) begin for (int i = 0; i < 16; i++) begin
write_reg(0, 8'h40 | i); write_reg(0, 8'h40 | i);
write_reg(1, edge_type[8*i +: 8]); write_reg(1, edge_type[8*i +: 8]);
end end
endtask endtask
task set_interrupts(logic [255:0] ints); task set_interrupts(logic [127:0] ints);
int_in = ints; int_in = ints;
@(posedge r_clk_cpu); @(posedge r_clk_cpu);
endtask endtask

View File

@@ -1,5 +1,7 @@
module interrupt_controller module interrupt_controller
( #(
parameter N_INTERRUPTS = 128
)(
input clk, input clk,
input reset, input reset,
input [7:0] i_data, input [7:0] i_data,
@@ -8,15 +10,15 @@ module interrupt_controller
input cs, input cs,
input rwb, input rwb,
input [255:0] int_in, input [N_INTERRUPTS-1:0] int_in,
output logic int_out output logic int_out
); );
logic w_enable_write; logic w_enable_write;
logic [7:0] w_enable_data; 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; logic [4:0] w_byte_sel;
@@ -24,7 +26,7 @@ logic [7:0] irq_val;
byte_sel_register #( byte_sel_register #(
.DATA_WIDTH(8), .DATA_WIDTH(8),
.ADDR_WIDTH(32) .ADDR_WIDTH(N_INTERRUPTS/8)
) reg_enable ( ) reg_enable (
.i_clk(~clk), .i_clk(~clk),
.i_reset(reset), .i_reset(reset),
@@ -40,17 +42,17 @@ logic we, re;
assign we = cs & ~rwb; assign we = cs & ~rwb;
assign re = 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; assign int_masked = int_in & w_enable_full_data;
logic w_type_write; logic w_type_write;
logic [7:0] w_type_data; 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 #( byte_sel_register #(
.DATA_WIDTH(8), .DATA_WIDTH(8),
.ADDR_WIDTH(32) .ADDR_WIDTH(N_INTERRUPTS/8)
) reg_type ( ) reg_type (
.i_clk(~clk), .i_clk(~clk),
.i_reset(reset), .i_reset(reset),
@@ -65,7 +67,7 @@ logic [7:0] cmd, cmd_next;
logic w_eoi; logic w_eoi;
logic [255:0] r_int, r_int_next; logic [N_INTERRUPTS-1:0] r_int, r_int_next;
always_comb begin always_comb begin
w_eoi = 0; w_eoi = 0;
@@ -108,13 +110,13 @@ always_comb begin
int_out = |r_int; int_out = |r_int;
irq_val = 8'hff; 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 if (r_int[i] == 1) begin
irq_val = i; irq_val = i;
end end
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]) case (w_type_full_data[i])
0: begin // Edge triggered 0: begin // Edge triggered
if (w_eoi && i == irq_val) begin if (w_eoi && i == irq_val) begin

View File

@@ -34,7 +34,7 @@ IRQ_CMD_EOI = $ff
cmd_all: ; Send the same value to all 32 bytes cmd_all: ; Send the same value to all 32 bytes
txa txa
add #$20 add #$10
sta tmp1 sta tmp1
loop: loop:
txa txa
@@ -51,12 +51,10 @@ loop:
; void enable_irq(uint8_t type, uint8_t irqnum); ; void enable_irq(uint8_t type, uint8_t irqnum);
; in A: ; in A:
.proc _enable_irq .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 pha
lsr lsr
lsr lsr
lsr
lsr
lsr ; A is now bytesel lsr ; A is now bytesel
sta tmp2 ; tmp2 is now bytesel sta tmp2 ; tmp2 is now bytesel
add #IRQ_CMD_ENABLE add #IRQ_CMD_ENABLE
@@ -97,13 +95,12 @@ L3: sta IRQ_DAT_ADDR
.endproc .endproc
; TODO this is mostly the same as enable, why copy?
.proc _disable_irq .proc _disable_irq
; Decide which byte we need to modify by dividing by 32 (>> 5) ; Decide which byte we need to modify by dividing by 32 (>> 5)
pha pha
lsr lsr
lsr lsr
lsr
lsr
lsr ; A is now bytesel lsr ; A is now bytesel
add #IRQ_CMD_ENABLE add #IRQ_CMD_ENABLE
sta IRQ_CMD_ADDR sta IRQ_CMD_ADDR

View File

@@ -54,7 +54,7 @@ _init:
cmd_all: cmd_all:
txa txa
add #$20 add #$10
sta tmp1 sta tmp1
loop: loop:
txa txa