`timescale 1ns/1ps `include "../util/clog2.vh" module mcu #( 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, output wire o_test ); localparam WITH_CSR = 1; localparam regs = 32+WITH_CSR*4; localparam rf_width = 8; wire rst; wire rst_mem_reason; wire timer_irq; assign rst = i_rst | rst_mem_reason; assign o_test = timer_irq; // Busses // CPU->memory wire [31:0] wb_mem_adr; wire [31:0] wb_mem_dat; wire [3:0] wb_mem_sel; wire wb_mem_we; wire wb_mem_stb; wire [31:0] wb_mem_rdt; wire wb_mem_ack; // CPU->peripherals wire [31:0] wb_ext_adr; wire [31:0] wb_ext_dat; wire [3:0] wb_ext_sel; wire wb_ext_we; wire wb_ext_stb; wire [31:0] wb_ext_rdt; wire wb_ext_ack; // CPU->RF wire [6+WITH_CSR:0] rf_waddr; wire [rf_width-1:0] rf_wdata; wire rf_wen; wire [6+WITH_CSR:0] rf_raddr; wire [rf_width-1:0] rf_rdata; wire rf_ren; // combined RF and mem bus to actual RAM wire [`CLOG2(memsize)-1:0] sram_waddr; wire [rf_width-1:0] sram_wdata; wire sram_wen; wire [`CLOG2(memsize)-1:0] sram_raddr; wire [rf_width-1:0] sram_rdata; wire sram_ren; // GPIO 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; // 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 servile #( .reset_pc(32'h0000_0000), .reset_strategy("MINI"), .rf_width(rf_width), .sim(sim), .with_csr(WITH_CSR), .with_c(0), .with_mdu(0) ) servile ( .i_clk(i_clk), .i_rst(rst), .i_timer_irq(1'b0), //timer_irq), //Memory interface .o_wb_mem_adr(wb_mem_adr), .o_wb_mem_dat(wb_mem_dat), .o_wb_mem_sel(wb_mem_sel), .o_wb_mem_we(wb_mem_we), .o_wb_mem_stb(wb_mem_stb), .i_wb_mem_rdt(wb_mem_rdt), .i_wb_mem_ack(wb_mem_ack), //Extension interface .o_wb_ext_adr(wb_ext_adr), .o_wb_ext_dat(wb_ext_dat), .o_wb_ext_sel(wb_ext_sel), .o_wb_ext_we(wb_ext_we), .o_wb_ext_stb(wb_ext_stb), .i_wb_ext_rdt(wb_ext_rdt), .i_wb_ext_ack(wb_ext_ack), //RF IF .o_rf_waddr(rf_waddr), .o_rf_wdata(rf_wdata), .o_rf_wen(rf_wen), .o_rf_raddr(rf_raddr), .o_rf_ren(rf_ren), .i_rf_rdata(rf_rdata) ); // WB arbiter combining RF and mem interfaces into 1 // 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 (rst), .i_waddr(rf_waddr), .i_wdata(rf_wdata), .i_wen(rf_wen), .i_raddr(rf_raddr), .o_rdata(rf_rdata), .i_ren(rf_ren), .o_sram_waddr(sram_waddr), .o_sram_wdata(sram_wdata), .o_sram_wen(sram_wen), .o_sram_raddr(sram_raddr), .i_sram_rdata(sram_rdata), // .o_sram_ren(sram_ren), .i_wb_adr(wb_mem_adr[`CLOG2(memsize)-1:2]), .i_wb_stb(wb_mem_stb), .i_wb_we(wb_mem_we) , .i_wb_sel(wb_mem_sel), .i_wb_dat(wb_mem_dat), .o_wb_rdt(wb_mem_rdt), .o_wb_ack(wb_mem_ack) ); memory #( .memfile(memfile), .depth(memsize), .sim(sim) ) mem ( .i_clk(i_clk), .i_rst(i_rst), .i_waddr(sram_waddr), .i_wdata(sram_wdata), .i_wen(sram_wen), .i_raddr(sram_raddr), .o_rdata(sram_rdata), .o_core_reset(rst_mem_reason) ); 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), .o_wb_rdt(wb_ext_rdt), .o_wb_ack(wb_ext_ack), // Peripheral IO .i_gpio(GPI), .o_gpio(GPO), .o_timer_irq(timer_irq) ); endmodule