blob: 2a597e033a5d82473fdf2baef8295c09ff0e725f [file] [log] [blame]
`default_nettype none
/*
* SPDX-FileCopyrightText: 2015 Clifford Wolf
* PicoSoC - A simple example SoC using PicoRV32
*
* Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Revision 1, July 2019: Added signals to drive flash_clk and flash_csb
* output enable (inverted), tied to reset so that the flash is completely
* isolated from the processor when the processor is in reset.
*
* Also: Made ram_wenb a 4-bit bus so that the memory access can be made
* byte-wide for byte-wide instructions.
*
* SPDX-License-Identifier: ISC
*/
`ifdef PICORV32_V
`error "mgmt_soc.v must be read before picorv32.v!"
`endif
`define PICORV32_REGS mgmt_soc_regs
`include "picorv32.v"
`include "spimemio.v"
`include "simpleuart.v"
`include "simple_spi_master.v"
`include "counter_timer_high.v"
`include "counter_timer_low.v"
`include "wb_intercon.v"
`include "mem_wb.v"
`include "gpio_wb.v"
`include "sysctrl.v"
`include "la_wb.v"
`include "mprj_ctrl.v"
`include "convert_gpio_sigs.v"
module mgmt_soc (
`ifdef USE_POWER_PINS
inout vdd1v8, /* 1.8V domain */
inout vss,
`endif
input clk,
input resetn,
// Trap state from CPU
output trap,
// GPIO (one pin)
output gpio_out_pad, // Connect to out on gpio pad
input gpio_in_pad, // Connect to in on gpio pad
output gpio_mode0_pad, // Connect to dm[0] on gpio pad
output gpio_mode1_pad, // Connect to dm[2] on gpio pad
output gpio_outenb_pad, // Connect to oe_n on gpio pad
output gpio_inenb_pad, // Connect to inp_dis on gpio pad
// LA signals
input [127:0] la_input, // From User Project to cpu
output [127:0] la_output, // From CPU to User Project
output [127:0] la_oenb, // LA output enable (active low)
output [127:0] la_iena, // LA input enable (active high)
// User Project I/O Configuration (serial load)
input mprj_vcc_pwrgood,
input mprj2_vcc_pwrgood,
input mprj_vdd_pwrgood,
input mprj2_vdd_pwrgood,
output mprj_io_loader_resetn,
output mprj_io_loader_clock,
output mprj_io_loader_data_1,
output mprj_io_loader_data_2,
// User Project pad data (when management SoC controls the pad)
input [`MPRJ_IO_PADS-1:0] mgmt_in_data,
output [`MPRJ_IO_PADS-1:0] mgmt_out_data,
output [`MPRJ_IO_PADS-1:0] mgmt_oeb_data,
output [`MPRJ_PWR_PADS-1:0] pwr_ctrl_out,
// IRQ
input irq_spi, // IRQ from standalone SPI
input [2:0] user_irq, // IRQ from user project
output [2:0] user_irq_ena, // enable IRQ from user project
// Flash memory control (SPI master)
output flash_csb,
output flash_clk,
output flash_csb_oeb,
output flash_clk_oeb,
output flash_io0_oeb,
output flash_io1_oeb,
output flash_io2_oeb,
output flash_io3_oeb,
output flash_csb_ieb,
output flash_clk_ieb,
output flash_io0_ieb,
output flash_io1_ieb,
output flash_io2_ieb,
output flash_io3_ieb,
output flash_io0_do,
output flash_io1_do,
input flash_io0_di,
input flash_io1_di,
input flash_io2_di,
input flash_io3_di,
// SPI pass-thru mode
input pass_thru_mgmt,
input pass_thru_mgmt_csb,
input pass_thru_mgmt_sck,
input pass_thru_mgmt_sdi,
output pass_thru_mgmt_sdo,
// State of JTAG and SDO pins (override for management output use)
output sdo_oenb_state,
output jtag_oenb_state,
// State of flash_io2 and flash_io3 pins (override for management output use)
output flash_io2_oenb_state,
output flash_io3_oenb_state,
// SPI master->slave direct link
output hk_connect,
// User clock monitoring
input user_clk,
// WB MI A (User project)
input mprj_ack_i,
input [31:0] mprj_dat_i,
output mprj_cyc_o,
output mprj_stb_o,
output mprj_we_o,
output [3:0] mprj_sel_o,
output [31:0] mprj_adr_o,
output [31:0] mprj_dat_o,
// MGMT area R/W interface for mgmt RAM
output [`RAM_BLOCKS-1:0] mgmt_ena,
output [(`RAM_BLOCKS*4)-1:0] mgmt_wen_mask,
output [`RAM_BLOCKS-1:0] mgmt_wen,
output [7:0] mgmt_addr,
output [31:0] mgmt_wdata,
input [(`RAM_BLOCKS*32)-1:0] mgmt_rdata,
// MGMT area RO interface for user RAM
output mgmt_ena_ro,
output [7:0] mgmt_addr_ro,
input [31:0] mgmt_rdata_ro
);
/* Memory reverted back to 256 words while memory has to be synthesized */
parameter [31:0] STACKADDR = (4*(`MEM_WORDS)); // end of memory
parameter [31:0] PROGADDR_RESET = 32'h 1000_0000;
parameter [31:0] PROGADDR_IRQ = 32'h 0000_0000;
// Slaves Base Addresses
parameter RAM_BASE_ADR = 32'h 0000_0000;
parameter STORAGE_RW_ADR = 32'h 0100_0000;
parameter STORAGE_RO_ADR = 32'h 0200_0000;
parameter FLASH_BASE_ADR = 32'h 1000_0000;
parameter UART_BASE_ADR = 32'h 2000_0000;
parameter GPIO_BASE_ADR = 32'h 2100_0000;
parameter COUNTER_TIMER0_BASE_ADR = 32'h 2200_0000;
parameter COUNTER_TIMER1_BASE_ADR = 32'h 2300_0000;
parameter SPI_MASTER_BASE_ADR = 32'h 2400_0000;
parameter LA_BASE_ADR = 32'h 2500_0000;
parameter MPRJ_CTRL_ADR = 32'h 2600_0000;
parameter FLASH_CTRL_CFG = 32'h 2D00_0000;
parameter SYS_BASE_ADR = 32'h 2F00_0000;
parameter MPRJ_BASE_ADR = 32'h 3000_0000; // WB MI A
// UART
parameter UART_CLK_DIV = 8'h00;
parameter UART_DATA = 8'h04;
// SPI Master
parameter SPI_MASTER_CONFIG = 8'h00;
parameter SPI_MASTER_DATA = 8'h04;
// Counter-timer 0
parameter COUNTER_TIMER0_CONFIG = 8'h00;
parameter COUNTER_TIMER0_VALUE = 8'h04;
parameter COUNTER_TIMER0_DATA = 8'h08;
// Counter-timer 1
parameter COUNTER_TIMER1_CONFIG = 8'h00;
parameter COUNTER_TIMER1_VALUE = 8'h04;
parameter COUNTER_TIMER1_DATA = 8'h08;
// SOC GPIO
parameter GPIO_DATA = 8'h00;
parameter GPIO_ENA = 8'h04;
parameter GPIO_PU = 8'h08;
parameter GPIO_PD = 8'h0c;
// LA
parameter LA_DATA_0 = 8'h00;
parameter LA_DATA_1 = 8'h04;
parameter LA_DATA_2 = 8'h08;
parameter LA_DATA_3 = 8'h0c;
parameter LA_OENB_0 = 8'h10;
parameter LA_OENB_1 = 8'h14;
parameter LA_OENB_2 = 8'h18;
parameter LA_OENB_3 = 8'h1c;
parameter LA_IENA_0 = 8'h20;
parameter LA_IENA_1 = 8'h24;
parameter LA_IENA_2 = 8'h28;
parameter LA_IENA_3 = 8'h2c;
parameter LA_SAMPLE = 8'h30;
// System Control Registers
parameter PWRGOOD = 8'h00;
parameter CLK_OUT = 8'h04;
parameter TRAP_OUT = 8'h08;
parameter IRQ_SRC = 8'h0c;
// Storage area RAM blocks
parameter [(`RAM_BLOCKS*24)-1:0] RW_BLOCKS_ADR = {
{24'h 10_0000},
{24'h 00_0000}
};
parameter [23:0] RO_BLOCKS_ADR = {
{24'h 00_0000}
};
// Wishbone Interconnect
localparam ADR_WIDTH = 32;
localparam DAT_WIDTH = 32;
localparam NUM_SLAVES = 14;
parameter [NUM_SLAVES*ADR_WIDTH-1: 0] ADR_MASK = {
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}},
{8'hFF, {ADR_WIDTH-8{1'b0}}}
};
parameter [NUM_SLAVES*ADR_WIDTH-1: 0] SLAVE_ADR = {
{SYS_BASE_ADR},
{FLASH_CTRL_CFG},
{MPRJ_BASE_ADR},
{MPRJ_CTRL_ADR},
{LA_BASE_ADR},
{SPI_MASTER_BASE_ADR},
{COUNTER_TIMER1_BASE_ADR},
{COUNTER_TIMER0_BASE_ADR},
{GPIO_BASE_ADR},
{UART_BASE_ADR},
{FLASH_BASE_ADR},
{STORAGE_RO_ADR},
{STORAGE_RW_ADR},
{RAM_BASE_ADR}
};
// The following functions are connected to specific user project
// area pins, when under control of the management area (during
// startup, and when not otherwise programmed for the user project).
// JTAG = jtag_out (inout)
// SDO = sdo_out (output) (shared with SPI master)
// SDI = mgmt_in_data[2] (input) (shared with SPI master)
// CSB = mgmt_in_data[3] (input) (shared with SPI master)
// SCK = mgmt_in_data[4] (input) (shared with SPI master)
// ser_rx = mgmt_in_data[5] (input)
// ser_tx = mgmt_out_data[6] (output)
// irq_pin = mgmt_in_data[7] (input)
// flash_csb = mgmt_out_data[8] (output) (user area flash)
// flash_sck = mgmt_out_data[9] (output) (user area flash)
// flash_io0 = mgmt_in/out_data[10] (input) (user area flash)
// flash_io1 = mgmt_in/out_data[11] (output) (user area flash)
// irq2_pin = mgmt_in_data[12] (input)
// trap_mon = mgmt_in_data[13] (output)
// clk1_mon = mgmt_in_data[14] (output)
// clk2_mon = mgmt_in_data[15] (output)
// flash_io2 = mgmt_in_data[36] (inout) (management area flash)
// flash_io3 = mgmt_in_data[37] (inout) (management area flash)
// OEB lines for [0] and [1] are the only ones connected directly to
// the pad. All others have OEB controlled by the configuration bit
// in the control block.
// memory-mapped I/O control registers
wire gpio_pullup; // Intermediate GPIO pullup
wire gpio_pulldown; // Intermediate GPIO pulldown
wire gpio_outenb; // Intermediate GPIO out enable (bar)
wire gpio_out; // Intermediate GPIO output
wire trap_output_dest; // Trap signal output destination
wire clk1_output_dest; // Core clock1 signal output destination
wire clk2_output_dest; // Core clock2 signal output destination
wire irq_7_inputsrc; // IRQ 7 source
wire irq_8_inputsrc; // IRQ 8 source
// Convert GPIO signals to sky130_fd_io pad signals
convert_gpio_sigs convert_gpio_bit (
.gpio_out(gpio_out),
.gpio_outenb(gpio_outenb),
.gpio_pu(gpio_pullup),
.gpio_pd(gpio_pulldown),
.gpio_out_pad(gpio_out_pad),
.gpio_outenb_pad(gpio_outenb_pad),
.gpio_inenb_pad(gpio_inenb_pad),
.gpio_mode1_pad(gpio_mode1_pad),
.gpio_mode0_pad(gpio_mode0_pad)
);
reg [31:0] irq;
wire irq_7;
wire irq_8;
wire irq_stall;
wire irq_uart;
wire irq_spi_master;
wire irq_counter_timer0;
wire irq_counter_timer1;
wire ser_tx;
wire wb_clk_i;
wire wb_rst_i;
assign irq_stall = 0;
assign irq_7 = (irq_7_inputsrc == 1'b1) ? mgmt_in_data[7] : 1'b0;
assign irq_8 = (irq_8_inputsrc == 1'b1) ? mgmt_in_data[12] : 1'b0;
always @* begin
irq = 0;
irq[3] = irq_stall;
irq[4] = irq_uart;
irq[6] = irq_spi;
irq[7] = irq_7;
irq[8] = irq_8;
irq[9] = irq_spi_master;
irq[10] = irq_counter_timer0;
irq[11] = irq_counter_timer1;
irq[14:12] = user_irq;
end
// Assumption : no syscon module and wb_clk is the clock coming from the
// caravel_clocking module
assign wb_clk_i = clk;
assign wb_rst_i = ~resetn; // Redundant
// Wishbone Master
wire [31:0] cpu_adr_o;
wire [31:0] cpu_dat_i;
wire [3:0] cpu_sel_o;
wire cpu_we_o;
wire cpu_cyc_o;
wire cpu_stb_o;
wire [31:0] cpu_dat_o;
wire cpu_ack_i;
wire mem_instr;
picorv32_wb #(
.STACKADDR(STACKADDR),
.PROGADDR_RESET(PROGADDR_RESET),
.PROGADDR_IRQ(PROGADDR_IRQ),
.BARREL_SHIFTER(1),
.COMPRESSED_ISA(1),
.ENABLE_MUL(1),
.ENABLE_DIV(1),
.ENABLE_IRQ(1),
.ENABLE_IRQ_QREGS(0)
) cpu (
.wb_clk_i (wb_clk_i),
.wb_rst_i (wb_rst_i),
.trap (trap),
.irq (irq),
.mem_instr(mem_instr),
.wbm_adr_o(cpu_adr_o),
.wbm_dat_i(cpu_dat_i),
.wbm_stb_o(cpu_stb_o),
.wbm_ack_i(cpu_ack_i),
.wbm_cyc_o(cpu_cyc_o),
.wbm_dat_o(cpu_dat_o),
.wbm_we_o(cpu_we_o),
.wbm_sel_o(cpu_sel_o)
);
// Wishbone Slave SPIMEMIO
wire spimemio_flash_stb_i;
wire spimemio_flash_ack_o;
wire [31:0] spimemio_flash_dat_o;
wire spimemio_cfg_stb_i;
wire spimemio_cfg_ack_o;
wire [31:0] spimemio_cfg_dat_o;
wire spimemio_quad_mode;
wire flash_io2_do;
wire flash_io3_do;
spimemio_wb spimemio (
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
.wb_sel_i(cpu_sel_o),
.wb_we_i(cpu_we_o),
.wb_cyc_i(cpu_cyc_o),
// FLash Slave
.wb_flash_stb_i(spimemio_flash_stb_i),
.wb_flash_ack_o(spimemio_flash_ack_o),
.wb_flash_dat_o(spimemio_flash_dat_o),
// Config Register Slave
.wb_cfg_stb_i(spimemio_cfg_stb_i),
.wb_cfg_ack_o(spimemio_cfg_ack_o),
.wb_cfg_dat_o(spimemio_cfg_dat_o),
.quad_mode(spimemio_quad_mode),
.pass_thru(pass_thru_mgmt),
.pass_thru_csb(pass_thru_mgmt_csb),
.pass_thru_sck(pass_thru_mgmt_sck),
.pass_thru_sdi(pass_thru_mgmt_sdi),
.pass_thru_sdo(pass_thru_mgmt_sdo),
.flash_csb (flash_csb),
.flash_clk (flash_clk),
.flash_csb_oeb (flash_csb_oeb),
.flash_clk_oeb (flash_clk_oeb),
.flash_io0_oeb (flash_io0_oeb),
.flash_io1_oeb (flash_io1_oeb),
.flash_io2_oeb (flash_io2_oeb), // through GPIO 36
.flash_io3_oeb (flash_io3_oeb), // through GPIO 37
.flash_csb_ieb (flash_csb_ieb),
.flash_clk_ieb (flash_clk_ieb),
.flash_io0_ieb (flash_io0_ieb),
.flash_io1_ieb (flash_io1_ieb),
.flash_io2_ieb (), // unused
.flash_io3_ieb (), // unused
.flash_io0_do (flash_io0_do),
.flash_io1_do (flash_io1_do),
.flash_io2_do (flash_io2_do), // through GPIO 36
.flash_io3_do (flash_io3_do), // through GPIO 37
.flash_io0_di (flash_io0_di),
.flash_io1_di (flash_io1_di),
.flash_io2_di (mgmt_in_data[(`MPRJ_IO_PADS)-2]),
.flash_io3_di (mgmt_in_data[(`MPRJ_IO_PADS)-1])
);
// Wishbone Slave uart
wire uart_stb_i;
wire uart_ack_o;
wire [31:0] uart_dat_o;
wire uart_enabled;
simpleuart_wb #(
.BASE_ADR(UART_BASE_ADR),
.CLK_DIV(UART_CLK_DIV),
.DATA(UART_DATA)
) simpleuart (
// Wishbone Interface
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
.wb_sel_i(cpu_sel_o),
.wb_we_i(cpu_we_o),
.wb_cyc_i(cpu_cyc_o),
.wb_stb_i(uart_stb_i),
.wb_ack_o(uart_ack_o),
.wb_dat_o(uart_dat_o),
.uart_enabled(uart_enabled),
.ser_tx(ser_tx),
.ser_rx(mgmt_in_data[5])
);
// Wishbone SPI master
wire spi_master_stb_i;
wire spi_master_ack_o;
wire [31:0] spi_master_dat_o;
wire spi_enabled;
wire spi_csb, spi_sck, spi_sdo;
simple_spi_master_wb #(
.BASE_ADR(SPI_MASTER_BASE_ADR),
.CONFIG(SPI_MASTER_CONFIG),
.DATA(SPI_MASTER_DATA)
) simple_spi_master_inst (
// Wishbone Interface
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
.wb_sel_i(cpu_sel_o),
.wb_we_i(cpu_we_o),
.wb_cyc_i(cpu_cyc_o),
.wb_stb_i(spi_master_stb_i),
.wb_ack_o(spi_master_ack_o),
.wb_dat_o(spi_master_dat_o),
.hk_connect(hk_connect),
.spi_enabled(spi_enabled),
.csb(spi_csb),
.sck(spi_sck),
.sdo(spi_sdo),
.sdi(mgmt_in_data[1]),
.sdoenb(),
.irq(irq_spi_master)
);
wire counter_timer_strobe, counter_timer_offset;
wire counter_timer0_enable, counter_timer1_enable;
wire counter_timer0_stop, counter_timer1_stop;
// Wishbone Counter-timer 0
wire counter_timer0_stb_i;
wire counter_timer0_ack_o;
wire [31:0] counter_timer0_dat_o;
counter_timer_low_wb #(
.BASE_ADR(COUNTER_TIMER0_BASE_ADR),
.CONFIG(COUNTER_TIMER0_CONFIG),
.VALUE(COUNTER_TIMER0_VALUE),
.DATA(COUNTER_TIMER0_DATA)
) counter_timer_0 (
// Wishbone Interface
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
.wb_sel_i(cpu_sel_o),
.wb_we_i(cpu_we_o),
.wb_cyc_i(cpu_cyc_o),
.wb_stb_i(counter_timer0_stb_i),
.wb_ack_o(counter_timer0_ack_o),
.wb_dat_o(counter_timer0_dat_o),
.enable_in(counter_timer1_enable),
.stop_in(counter_timer1_stop),
.strobe(counter_timer_strobe),
.is_offset(counter_timer_offset),
.enable_out(counter_timer0_enable),
.stop_out(counter_timer0_stop),
.irq(irq_counter_timer0)
);
// Wishbone Counter-timer 1
wire counter_timer1_stb_i;
wire counter_timer1_ack_o;
wire [31:0] counter_timer1_dat_o;
counter_timer_high_wb #(
.BASE_ADR(COUNTER_TIMER1_BASE_ADR),
.CONFIG(COUNTER_TIMER1_CONFIG),
.VALUE(COUNTER_TIMER1_VALUE),
.DATA(COUNTER_TIMER1_DATA)
) counter_timer_1 (
// Wishbone Interface
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
.wb_sel_i(cpu_sel_o),
.wb_we_i(cpu_we_o),
.wb_cyc_i(cpu_cyc_o),
.wb_stb_i(counter_timer1_stb_i),
.wb_ack_o(counter_timer1_ack_o),
.wb_dat_o(counter_timer1_dat_o),
.enable_in(counter_timer0_enable),
.strobe(counter_timer_strobe),
.stop_in(counter_timer0_stop),
.is_offset(counter_timer_offset),
.enable_out(counter_timer1_enable),
.stop_out(counter_timer1_stop),
.irq(irq_counter_timer1)
);
// Wishbone Slave GPIO Registers
wire gpio_stb_i;
wire gpio_ack_o;
wire [31:0] gpio_dat_o;
gpio_wb #(
.BASE_ADR(GPIO_BASE_ADR),
.GPIO_DATA(GPIO_DATA),
.GPIO_ENA(GPIO_ENA),
.GPIO_PD(GPIO_PD),
.GPIO_PU(GPIO_PU)
) gpio_wb (
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
.wb_sel_i(cpu_sel_o),
.wb_we_i(cpu_we_o),
.wb_cyc_i(cpu_cyc_o),
.wb_stb_i(gpio_stb_i),
.wb_ack_o(gpio_ack_o),
.wb_dat_o(gpio_dat_o),
.gpio_in_pad(gpio_in_pad),
.gpio(gpio_out),
.gpio_oeb(gpio_outenb),
.gpio_pu(gpio_pullup),
.gpio_pd(gpio_pulldown)
);
// Wishbone Slave System Control Register
wire sys_stb_i;
wire sys_ack_o;
wire [31:0] sys_dat_o;
sysctrl_wb #(
.BASE_ADR(SYS_BASE_ADR),
.PWRGOOD(PWRGOOD),
.CLK_OUT(CLK_OUT),
.TRAP_OUT(TRAP_OUT),
.IRQ_SRC(IRQ_SRC)
) sysctrl (
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
.wb_sel_i(cpu_sel_o),
.wb_we_i(cpu_we_o),
.wb_cyc_i(cpu_cyc_o),
.wb_stb_i(sys_stb_i),
.wb_ack_o(sys_ack_o),
.wb_dat_o(sys_dat_o),
.usr1_vcc_pwrgood(mprj_vcc_pwrgood),
.usr2_vcc_pwrgood(mprj2_vcc_pwrgood),
.usr1_vdd_pwrgood(mprj_vdd_pwrgood),
.usr2_vdd_pwrgood(mprj2_vdd_pwrgood),
.trap_output_dest(trap_output_dest),
.clk1_output_dest(clk1_output_dest),
.clk2_output_dest(clk2_output_dest),
.irq_7_inputsrc(irq_7_inputsrc),
.irq_8_inputsrc(irq_8_inputsrc)
);
// Logic Analyzer
wire la_stb_i;
wire la_ack_o;
wire [31:0] la_dat_o;
la_wb #(
.BASE_ADR(LA_BASE_ADR),
.LA_DATA_0(LA_DATA_0),
.LA_DATA_1(LA_DATA_1),
.LA_DATA_3(LA_DATA_3),
.LA_OENB_0(LA_OENB_0),
.LA_OENB_1(LA_OENB_1),
.LA_OENB_2(LA_OENB_2),
.LA_OENB_3(LA_OENB_3),
.LA_IENA_0(LA_IENA_0),
.LA_IENA_1(LA_IENA_1),
.LA_IENA_2(LA_IENA_2),
.LA_IENA_3(LA_IENA_3),
.LA_SAMPLE(LA_SAMPLE)
) la (
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
.wb_sel_i(cpu_sel_o),
.wb_we_i(cpu_we_o),
.wb_cyc_i(cpu_cyc_o),
.wb_stb_i(la_stb_i),
.wb_ack_o(la_ack_o),
.wb_dat_o(la_dat_o),
.la_data(la_output),
.la_data_in(la_input),
.la_oenb(la_oenb),
.la_iena(la_iena)
);
// User project WB MI A port
assign mprj_cyc_o = cpu_cyc_o;
assign mprj_we_o = cpu_we_o;
assign mprj_sel_o = cpu_sel_o;
assign mprj_adr_o = cpu_adr_o;
assign mprj_dat_o = cpu_dat_o;
// WB Slave User Project Control
wire mprj_ctrl_stb_i;
wire mprj_ctrl_ack_o;
wire [31:0] mprj_ctrl_dat_o;
wire [`MPRJ_IO_PADS-1:0] mgmt_out_pre;
// Bits assigned to specific functions as outputs prevent the mprj
// GPIO-as-output from applying data when that function is active
assign mgmt_out_data[`MPRJ_IO_PADS-3:16] = mgmt_out_pre[`MPRJ_IO_PADS-3:16];
// spimemio module controls last two data out lines when in quad mode.
// These go to GPIO 36 and 37. The input and OEB lines are routed
// individually and have their own independent signal names.
assign mgmt_out_data[`MPRJ_IO_PADS-1] = (spimemio_quad_mode) ?
flash_io3_do : mgmt_out_pre[`MPRJ_IO_PADS-1];
assign mgmt_out_data[`MPRJ_IO_PADS-2] = (spimemio_quad_mode) ?
flash_io2_do : mgmt_out_pre[`MPRJ_IO_PADS-2];
// Routing of output monitors (PLL, trap, clk1, clk2)
assign mgmt_out_data[15] = clk2_output_dest ? user_clk : mgmt_out_pre[15];
assign mgmt_out_data[14] = clk1_output_dest ? clk : mgmt_out_pre[14];
assign mgmt_out_data[13] = trap_output_dest ? trap : mgmt_out_pre[13];
assign mgmt_out_data[12:7] = mgmt_out_pre[12:7];
assign mgmt_out_data[6] = uart_enabled ? ser_tx : mgmt_out_pre[6];
assign mgmt_out_data[0] = mgmt_out_pre[0];
assign mgmt_out_data[1] = mgmt_out_pre[1];
assign mgmt_out_data[5] = mgmt_out_pre[5];
assign mgmt_out_data[2] = spi_enabled ? spi_sdo : mgmt_out_pre[2];
assign mgmt_out_data[3] = spi_enabled ? spi_csb : mgmt_out_pre[3];
assign mgmt_out_data[4] = spi_enabled ? spi_sck : mgmt_out_pre[4];
mprj_ctrl_wb #(
.BASE_ADR(MPRJ_CTRL_ADR)
) mprj_ctrl (
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
.wb_sel_i(cpu_sel_o),
.wb_we_i(cpu_we_o),
.wb_cyc_i(cpu_cyc_o),
.wb_stb_i(mprj_ctrl_stb_i),
.wb_ack_o(mprj_ctrl_ack_o),
.wb_dat_o(mprj_ctrl_dat_o),
.serial_clock(mprj_io_loader_clock),
.serial_resetn(mprj_io_loader_resetn),
.serial_data_out_1(mprj_io_loader_data_1),
.serial_data_out_2(mprj_io_loader_data_2),
.sdo_oenb_state(sdo_oenb_state),
.jtag_oenb_state(jtag_oenb_state),
.flash_io2_oenb_state(flash_io2_oenb_state),
.flash_io3_oenb_state(flash_io3_oenb_state),
.mgmt_gpio_out(mgmt_out_pre),
.mgmt_gpio_oeb(mgmt_oeb_data),
.mgmt_gpio_in(mgmt_in_data),
.pwr_ctrl_out(pwr_ctrl_out),
.user_irq_ena(user_irq_ena)
);
// Wishbone Slave RAM
wire mem_stb_i;
wire mem_ack_o;
wire [31:0] mem_dat_o;
mem_wb soc_mem (
`ifdef USE_POWER_PINS
.VPWR(vdd1v8),
.VGND(vss),
`endif
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
.wb_sel_i(cpu_sel_o),
.wb_we_i(cpu_we_o),
.wb_cyc_i(cpu_cyc_o),
.wb_stb_i(mem_stb_i),
.wb_ack_o(mem_ack_o),
.wb_dat_o(mem_dat_o)
);
wire stg_rw_stb_i;
wire stg_ro_stb_i;
wire stg_rw_ack_o;
wire stg_ro_ack_o;
wire [31:0] stg_rw_dat_o;
wire [31:0] stg_ro_dat_o;
// Storage area wishbone brige
storage_bridge_wb #(
.RW_BLOCKS_ADR(RW_BLOCKS_ADR),
.RO_BLOCKS_ADR(RO_BLOCKS_ADR)
) wb_bridge (
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
.wb_sel_i(cpu_sel_o),
.wb_we_i(cpu_we_o),
.wb_cyc_i(cpu_cyc_o),
.wb_stb_i({stg_ro_stb_i, stg_rw_stb_i}),
.wb_ack_o({stg_ro_ack_o, stg_rw_ack_o}),
.wb_rw_dat_o(stg_rw_dat_o),
// MGMT_AREA RO WB Interface
.wb_ro_dat_o(stg_ro_dat_o),
// MGMT Area native memory interface
.mgmt_ena(mgmt_ena),
.mgmt_wen_mask(mgmt_wen_mask),
.mgmt_wen(mgmt_wen),
.mgmt_addr(mgmt_addr),
.mgmt_wdata(mgmt_wdata),
.mgmt_rdata(mgmt_rdata),
// MGMT_AREA RO interface
.mgmt_ena_ro(mgmt_ena_ro),
.mgmt_addr_ro(mgmt_addr_ro),
.mgmt_rdata_ro(mgmt_rdata_ro)
);
// Wishbone intercon logic
wb_intercon #(
.AW(ADR_WIDTH),
.DW(DAT_WIDTH),
.NS(NUM_SLAVES),
.ADR_MASK(ADR_MASK),
.SLAVE_ADR(SLAVE_ADR)
) intercon (
// Master Interface
.wbm_adr_i(cpu_adr_o),
.wbm_stb_i(cpu_stb_o),
.wbm_dat_o(cpu_dat_i),
.wbm_ack_o(cpu_ack_i),
// Slaves Interface
.wbs_stb_o({ sys_stb_i, spimemio_cfg_stb_i,
mprj_stb_o, mprj_ctrl_stb_i, la_stb_i,
spi_master_stb_i, counter_timer1_stb_i, counter_timer0_stb_i,
gpio_stb_i, uart_stb_i,
spimemio_flash_stb_i, stg_ro_stb_i, stg_rw_stb_i, mem_stb_i }),
.wbs_dat_i({ sys_dat_o, spimemio_cfg_dat_o,
mprj_dat_i, mprj_ctrl_dat_o, la_dat_o,
spi_master_dat_o, counter_timer1_dat_o, counter_timer0_dat_o,
gpio_dat_o, uart_dat_o,
spimemio_flash_dat_o, stg_ro_dat_o ,stg_rw_dat_o, mem_dat_o }),
.wbs_ack_i({ sys_ack_o, spimemio_cfg_ack_o,
mprj_ack_i, mprj_ctrl_ack_o, la_ack_o,
spi_master_ack_o, counter_timer1_ack_o, counter_timer0_ack_o,
gpio_ack_o, uart_ack_o,
spimemio_flash_ack_o, stg_ro_ack_o, stg_rw_ack_o, mem_ack_o })
);
endmodule
// Implementation note:
// Replace the following two modules with wrappers for your SRAM cells.
module mgmt_soc_regs (
input clk, wen,
input [5:0] waddr,
input [5:0] raddr1,
input [5:0] raddr2,
input [31:0] wdata,
output [31:0] rdata1,
output [31:0] rdata2
);
reg [31:0] regs [0:31];
always @(posedge clk)
if (wen) regs[waddr[4:0]] <= wdata;
assign rdata1 = regs[raddr1[4:0]];
assign rdata2 = regs[raddr2[4:0]];
endmodule
`default_nettype wire