Added soclet with gpio banks to top

This commit is contained in:
2026-02-22 20:00:42 +01:00
parent a97028c2ba
commit 20cfece6e3
14 changed files with 321 additions and 172 deletions

77
rtl/core/soclet.v Normal file
View File

@@ -0,0 +1,77 @@
`timescale 1ns/1ps
module soclet #(
parameter memfile = "",
parameter memsize = 8192,
parameter sim = 1'b0
)(
input wire i_clk,
input wire i_rst,
input wire [31:0] i_GPI_A,
input wire [31:0] i_GPI_B,
input wire [31:0] i_GPI_C,
input wire [31:0] i_GPI_D,
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
);
wire [31:0] wb_adr;
wire [31:0] wb_dat;
wire [31:0] wb_rdt;
wire [3:0] wb_sel;
wire wb_we;
wire wb_stb;
wire wb_ack;
wire [4*32-1:0] GPO;
wire [4*32-1:0] GPI;
assign o_GPO_A = GPO[32*1-1:32*0];
assign o_GPO_B = GPO[32*2-1:32*1];
assign o_GPO_C = GPO[32*3-1:32*2];
assign o_GPO_D = GPO[32*4-1:32*3];
assign GPI[32*1-1:32*0] = i_GPI_A;
assign GPI[32*2-1:32*1] = i_GPI_B;
assign GPI[32*3-1:32*2] = i_GPI_C;
assign GPI[32*4-1:32*3] = i_GPI_D;
serving #(
.memfile(memfile),
.memsize(memsize),
.sim(sim),
.RESET_STRATEGY("MINI"),
.WITH_CSR(1)
) serv (
.i_clk(i_clk),
.i_rst(i_rst),
.i_timer_irq(1'b0),
.i_wb_rdt(wb_rdt),
.i_wb_ack(wb_ack),
.o_wb_adr(wb_adr),
.o_wb_dat(wb_dat),
.o_wb_sel(wb_sel),
.o_wb_we(wb_we),
.o_wb_stb(wb_stb)
);
wb_gpio_banks #(
.BASE_ADDR(32'h40000000),
.NUM_BANKS(4)
) gpio (
.i_wb_clk(i_clk),
.i_wb_rst(i_rst),
.i_wb_dat(wb_dat),
.i_wb_adr(wb_adr),
.i_wb_we(wb_we),
.i_wb_stb(wb_stb),
.i_wb_sel(wb_sel),
.i_gpio(GPI),
.o_wb_rdt(wb_rdt),
.o_wb_ack(wb_ack),
.o_gpio(GPO)
);
endmodule

View File

@@ -22,38 +22,36 @@ module top_generic(
.clk_out_15(clk_15)
);
reg [11:0] count;
localparam integer DIV_MAX = 100_000 - 1; // 1 ms tick at 100 MHz
reg [16:0] div_counter = 0; // enough bits for 100k (2^17=131072)
reg [31:0] freq;
always @(posedge clk_15) begin
if (!aresetn) begin
div_counter <= 0;
count <= 0;
end else begin
if (div_counter == DIV_MAX) begin
div_counter <= 0;
if (count == 12'd3999)
count <= 0; // wrap at 4000
else
count <= count + 1'b1; // increment every 1 ms
end else begin
div_counter <= div_counter + 1'b1;
end
end
freq <= count;
end
wire [31:0] GPIO_A;
wire [31:0] GPIO_B;
wire [31:0] GPIO_C;
wire [31:0] GPIO_D;
soclet #(
.memfile("../sw/sweep/sweep.hex")
) mcu (
.i_clk(clk_15),
.i_rst(!aresetn),
.i_GPI_A(GPIO_A),
.i_GPI_B(GPIO_B),
.i_GPI_C(GPIO_C),
.i_GPI_D(GPIO_D),
.o_GPO_A(GPIO_A),
.o_GPO_B(GPIO_B),
.o_GPO_C(GPIO_C),
.o_GPO_D(GPIO_D)
);
wire [15:0] sin_q15;
wire clk_en;
nco_q15 #(
.CLK_HZ(15_000_000),
.FS_HZ(40_000)
.FS_HZ(80_000)
) nco (
.clk (clk_15),
.rst_n (aresetn),
.freq_hz(freq),
.freq_hz(GPIO_A),
.sin_q15(sin_q15),
.cos_q15(),
.clk_en (clk_en)

View File

@@ -1,70 +0,0 @@
`timescale 1ns/1ps
module top_generic(
input wire aclk,
input wire aresetn,
output wire led_green,
output wire led_red,
output wire[5:0] r2r
);
// Clocking
wire clk_100;
wire clk_15;
assign clk_100 = aclk;
clk_gen clocking(
.clk_in(clk_100),
.clk_out_15(clk_15)
);
wire [31:0] wb_adr;
wire [31:0] wb_dat;
wire [31:0] wb_rdt;
wire [3:0] wb_sel;
wire wb_we;
wire wb_stb;
wire wb_ack;
wire [31:0] GPIO;
assign led_green = GPIO[0];
assign led_red = GPIO[1];
assign r2r = GPIO[8:2];
serving #(
.memfile("../sw/blinky/blinky.hex"),
.memsize(8192),
.sim(1'b0),
.RESET_STRATEGY("MINI"),
.WITH_CSR(1)
) serv (
.i_clk(clk_15),
.i_rst(!aresetn),
.i_timer_irq(1'b0),
.i_wb_rdt(wb_rdt),
.i_wb_ack(wb_ack),
.o_wb_adr(wb_adr),
.o_wb_dat(wb_dat),
.o_wb_sel(wb_sel),
.o_wb_we(wb_we),
.o_wb_stb(wb_stb)
);
wb_gpio #(
.address(32'h40000000)
) gpio (
.i_wb_clk(clk_15),
.i_wb_rst(!aresetn),
.i_wb_dat(wb_dat),
.i_wb_adr(wb_adr),
.i_wb_we(wb_we),
.i_wb_stb(wb_stb),
.i_wb_sel(wb_sel),
.o_wb_rdt(wb_rdt),
.o_wb_ack(wb_ack),
.o_gpio(GPIO)
);
endmodule

View File

@@ -8,6 +8,7 @@ module wb_gpio #(
input wire [3:0] i_wb_sel,
input wire i_wb_we,
input wire i_wb_stb,
input wire [31:0] i_gpio,
output reg [31:0] o_wb_rdt,
output reg o_wb_ack,
@@ -34,7 +35,7 @@ module wb_gpio #(
if (i_wb_rst) begin
o_wb_rdt <= 32'h0;
end else if (i_wb_stb && !i_wb_we) begin
o_wb_rdt <= o_gpio;
o_wb_rdt <= i_gpio;
end
end
@@ -51,4 +52,4 @@ module wb_gpio #(
end
end
endmodule
endmodule

63
rtl/wb/wb_gpio_banks.v Normal file
View File

@@ -0,0 +1,63 @@
`default_nettype none
module wb_gpio_banks #(
parameter integer NUM_BANKS = 4,
parameter [31:0] BASE_ADDR = 32'h8000_0000
) (
input wire i_wb_clk,
input wire i_wb_rst,
input wire [31:0] i_wb_adr,
input wire [31:0] i_wb_dat,
input wire [3:0] i_wb_sel,
input wire i_wb_we,
input wire i_wb_stb,
input wire [NUM_BANKS*32-1:0] i_gpio,
output reg [31:0] o_wb_rdt,
output reg o_wb_ack,
output wire [NUM_BANKS*32-1:0] o_gpio
);
wire [NUM_BANKS-1:0] bank_sel;
wire [NUM_BANKS-1:0] bank_stb;
wire [NUM_BANKS*32-1:0] bank_rdt;
wire [NUM_BANKS-1:0] bank_ack;
genvar gi;
generate
for (gi = 0; gi < NUM_BANKS; gi = gi + 1) begin : gen_gpio
localparam [31:0] BANK_ADDR = BASE_ADDR + (gi * 4);
assign bank_sel[gi] = (i_wb_adr == BANK_ADDR);
assign bank_stb[gi] = i_wb_stb & bank_sel[gi];
wb_gpio #(
.address(BANK_ADDR)
) u_gpio (
.i_wb_clk(i_wb_clk),
.i_wb_rst(i_wb_rst),
.i_wb_adr(i_wb_adr),
.i_wb_dat(i_wb_dat),
.i_wb_sel(i_wb_sel),
.i_wb_we(i_wb_we),
.i_wb_stb(bank_stb[gi]),
.i_gpio(i_gpio[gi*32 +: 32]),
.o_wb_rdt(bank_rdt[gi*32 +: 32]),
.o_wb_ack(bank_ack[gi]),
.o_gpio(o_gpio[gi*32 +: 32])
);
end
endgenerate
integer bi;
always @* begin
o_wb_rdt = 32'h0000_0000;
o_wb_ack = 1'b0;
for (bi = 0; bi < NUM_BANKS; bi = bi + 1) begin
if (bank_sel[bi]) begin
o_wb_rdt = bank_rdt[bi*32 +: 32];
o_wb_ack = bank_ack[bi];
end
end
end
endmodule