Add skeleton of interrupt controller

This commit is contained in:
Byron Lathi
2023-11-15 08:27:29 -08:00
parent 0fe57c6ad5
commit 2b248db94f
4 changed files with 158 additions and 6 deletions

View File

@@ -9,6 +9,8 @@ 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
#TODO implement something like sources.list
TOP_MODULE=sim_top
@@ -29,7 +31,7 @@ sim: $(TARGET)
full_sim: $(TARGET) $(SD_IMAGE)
vvp -i $(TARGET) -fst
mapper_tb: $(SRCS) $(TBS)
$(STANDALONE_TB): $(SRCS) $(TBS)
iverilog -g2005-sv $(FLAGS) -s $@ -o $@ $(INC) $(SRCS) $(TBS)
mapper_code_tb: $(SRCS) $(TBS) $(INIT_MEM)

View File

@@ -0,0 +1,93 @@
`timescale 1ns/1ps
module interrupt_controller_tb();
logic r_clk_cpu;
// clk_cpu
initial begin
r_clk_cpu <= '1;
forever begin
#125 r_clk_cpu <= ~r_clk_cpu;
end
end
logic reset;
logic addr;
logic [7:0] i_data;
logic [7:0] o_data;
logic cs;
logic rwb;
logic [255:0] int_in;
logic int_out;
interrupt_controller u_interrupt_controller(
.clk(r_clk_cpu),
.reset(reset),
.i_data(i_data),
.o_data(o_data),
.addr(addr),
.cs(cs),
.rwb(rwb),
.int_in(int_in),
.int_out(int_out2)
);
/* 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
initial begin
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);
write_reg(1, 8'hff);
write_reg(0, 8'h20);
write_reg(1, 8'hff);
repeat (5) @(posedge r_clk_cpu);
int_in = 1;
@(posedge r_clk_cpu)
int_in = 0;
repeat (5) @(posedge r_clk_cpu);
$finish();
end
initial
begin
$dumpfile("interrupt_controller_tb.vcd");
$dumpvars(0,interrupt_controller_tb);
end
endmodule

View File

@@ -4,6 +4,7 @@ module byte_sel_register
parameter ADDR_WIDTH = 32
)(
input i_clk,
input i_reset,
input i_write,
input [$clog2(ADDR_WIDTH)-1:0] i_byte_sel,
input [DATA_WIDTH-1:0] i_data,
@@ -14,11 +15,16 @@ module byte_sel_register
logic [DATA_WIDTH*ADDR_WIDTH-1:0] r_data;
assign o_data = r_data[DATA_WIDTH*i_byte_sel +: DATA_WIDTH];
assign o_full_data = r_data;
always_ff @(posedge i_clk) begin
r_data <= r_data;
if (i_write) begin
r_data[DATA_WIDTH*i_byte_sel +: DATA_WIDTH] <= i_data;
if (i_reset) begin
r_data <= '0;
end else begin
r_data <= r_data;
if (i_write) begin
r_data[DATA_WIDTH*i_byte_sel +: DATA_WIDTH] <= i_data;
end
end
end

View File

@@ -12,6 +12,7 @@ module interrupt_controller
output logic int_out
);
logic w_enable_write;
logic [7:0] w_enable_data;
logic [255:0] w_enable_full_data;
@@ -24,6 +25,7 @@ byte_sel_register #(
.ADDR_WIDTH(32)
) reg_enable (
.i_clk(clk),
.i_reset(reset),
.i_write(w_enable_write),
.i_byte_sel(w_byte_sel),
.i_data(i_data),
@@ -31,10 +33,16 @@ byte_sel_register #(
.o_full_data(w_enable_full_data)
);
logic we, re;
assign we = cs & ~rwb;
assign re = cs & rwb;
logic [255: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;
@@ -43,6 +51,7 @@ byte_sel_register #(
.ADDR_WIDTH(32)
) reg_type (
.i_clk(clk),
.i_reset(reset),
.i_write(w_type_write),
.i_byte_sel(w_byte_sel),
.i_data(i_data),
@@ -50,6 +59,8 @@ byte_sel_register #(
.o_full_data(w_type_full_data)
);
logic [7:0] cmd, cmd_next;
logic w_eoi;
logic [255:0] r_int, r_int_next;
@@ -59,10 +70,50 @@ always_comb begin
if (w_eoi) begin
r_int_next[irq_val] = 0;
end
if (addr == '0 && we) begin
cmd_next = i_data;
end else begin
cmd_next = cmd;
end
w_type_write = '0;
if (addr == '1) begin
unique casez (cmd)
8'h0?: begin
$display("Case 0 not handled");
end
8'h1?: begin
w_enable_write = we;
w_byte_sel = cmd[3:0];
o_data = w_enable_data;
end
8'h2?: begin
w_type_write = we;
w_byte_sel = cmd[3:0];
o_data = w_type_data;
end
8'hff: begin
$display("Not handled");
end
endcase
end
int_out = |r_int;
end
always_ff @(posedge clk) begin
r_int <= r_int_next;
always_ff @(negedge clk) begin
if (reset) begin
r_int <= '0;
end else begin
r_int <= r_int_next;
cmd <= cmd_next;
end
end
always_comb begin