Added timer, still wip

This commit is contained in:
2026-02-25 20:54:12 +01:00
parent f2f9644830
commit 3a3c951409
12 changed files with 768 additions and 203 deletions

View File

@@ -16,7 +16,8 @@ module mcu #(
output wire [31:0] o_GPO_A,
output wire [31:0] o_GPO_B,
output wire [31:0] o_GPO_C,
output wire [31:0] o_GPO_D
output wire [31:0] o_GPO_D,
output wire o_test
);
localparam WITH_CSR = 1;
localparam regs = 32+WITH_CSR*4;
@@ -26,7 +27,8 @@ module mcu #(
wire rst_mem_reason;
wire timer_irq;
assign rst = i_rst | rst_mem_reason;
assign timer_irq = 1'b0;
assign o_test = timer_irq;
// Busses
// CPU->memory
@@ -72,9 +74,6 @@ module mcu #(
assign GPI[32*3-1:32*2] = i_GPI_C;
assign GPI[32*4-1:32*3] = i_GPI_D;
assign wb_ext_ack = wb_ext_gpio_ack;
assign wb_ext_rdt = wb_ext_gpio_rdt;
// SERV core with mux splitting dbus into mem and ext and
// arbiter combining mem and ibus
// separate rst line to let other hardware keep core under reset
@@ -89,7 +88,7 @@ module mcu #(
) servile (
.i_clk(i_clk),
.i_rst(rst),
.i_timer_irq(timer_irq),
.i_timer_irq(1'b0), //timer_irq),
//Memory interface
.o_wb_mem_adr(wb_mem_adr),
@@ -119,14 +118,14 @@ module mcu #(
);
// WB arbiter combining RF and mem interfaces into 1
// Last 128 bytes are used for registers
// Last 128 bytes are used for registers
servile_rf_mem_if #(
.depth(memsize),
.rf_regs(regs)
) rf_mem_if (
.i_clk (i_clk),
.i_rst (i_rst),
.i_rst (rst),
.i_waddr(rf_waddr),
.i_wdata(rf_wdata),
.i_wen(rf_wen),
@@ -165,111 +164,20 @@ module mcu #(
.o_core_reset(rst_mem_reason)
);
wb_gpio_banks #(
.BASE_ADDR(32'h40000000),
.NUM_BANKS(4)
) gpio (
.i_wb_clk(i_clk),
.i_wb_rst(rst),
.i_wb_dat(wb_ext_dat),
mcu_peripherals peripherals (
.i_clk(i_clk),
.i_rst(rst),
.i_wb_adr(wb_ext_adr),
.i_wb_dat(wb_ext_dat),
.i_wb_sel(wb_ext_sel),
.i_wb_we(wb_ext_we),
.i_wb_stb(wb_ext_stb),
.i_wb_sel(wb_ext_sel),
.o_wb_rdt(wb_ext_rdt),
.o_wb_ack(wb_ext_ack),
// Peripheral IO
.i_gpio(GPI),
.o_gpio(GPO)
.o_gpio(GPO),
.o_timer_irq(timer_irq)
);
endmodule
module memory #(
parameter memfile = "",
parameter depth = 256,
parameter sim = 1'b0,
localparam aw = `CLOG2(depth)
)(
input wire i_clk,
input wire i_rst,
input wire [aw-1:0] i_waddr,
input wire [7:0] i_wdata,
input wire i_wen,
input wire [aw-1:0] i_raddr,
output reg [7:0] o_rdata,
output wire o_core_reset
);
// The actual memory
reg [7:0] mem [0:depth-1];
wire [aw-1:0] mem_adr;
assign mem_adr = (i_wen==1'b1) ? i_waddr :
i_raddr;
// Second port wishbone
wire [31:0] wb_adr;
wire [31:0] wb_dat;
reg [31:0] wb_rdt;
wire [3:0] wb_sel;
wire wb_cyc;
wire wb_we;
wire wb_stb;
reg wb_ack;
reg wb_req_d;
wire cmd_reset;
// Driven by JTAG
jtag_wb_bridge #(
.chain(1),
.byte_aligned(1)
) jtag_wb (
.i_clk(i_clk),
.i_rst(i_rst),
.o_wb_adr(wb_adr),
.o_wb_dat(wb_dat),
.o_wb_sel(wb_sel),
.o_wb_we(wb_we),
.o_wb_cyc(wb_cyc),
.o_wb_stb(wb_stb),
.i_wb_rdt(wb_rdt),
.i_wb_ack(wb_ack),
.o_cmd_reset(cmd_reset)
);
assign o_core_reset = cmd_reset;
// Read/Write
always @(posedge i_clk) begin
if (i_rst) begin
wb_req_d <= 1'b0;
wb_ack <= 1'b0;
wb_rdt <= 32'h00000000;
o_rdata <= 32'h00000000;
end else begin
if (i_wen)
mem[mem_adr] <= i_wdata;
o_rdata <= mem[mem_adr];
wb_req_d <= wb_stb && wb_cyc;
wb_ack <= wb_req_d;
if (wb_we && wb_stb && wb_cyc)
mem[wb_adr[aw-1:0]] <= wb_dat[7:0];
wb_rdt <= {24'h000000, mem[wb_adr[aw-1:0]]};
end
end
// Preload memory
integer i;
initial begin
if(sim==1'b1) begin
for (i = 0; i < depth; i = i + 1)
mem[i] = 8'h00;
end
if(|memfile) begin
$display("Preloading %m from %s", memfile);
$readmemh(memfile, mem);
end
end
endmodule
endmodule