aboutsummaryrefslogtreecommitdiff
/*
 * Topmost module in synthesis. It instantiates the intercon together with
 * stack machine as master and 3 slaves:
 *   slave 0 - embedded RAM (256x16) with memory initialized from file
 *   slave 1 - SRAM
 *   slave 2 - VGA text-mode controller
 *   slave 3 - SPI master controller
 *   slave 4 - UART controller (yet to be added)
 *   slave 5 - miscellaneous registers
 *
 * The memory map from stack machine's viewpoint is as follows:
 *   h000000 - h0001FF - embedded RAM
 *   h000200 - h07FFFF - undefined (actually, repetitions of embedded RAM)
 *   h080000 - h0FFFFF - SRAM
 *   h100000 - h1009FF - VGA text memory
 *   h100A00 - h100A01 - VGA power-on register
 *   h100A02 - h100FFF - undefined (actually, repetitions of VGA power-on reg)
 *   h101000 - h13FFFF - undefined (actually, repetitions of VGA memory & regs)
 *   h140000 - h1401FF - SPI data transfer memory
 *   h140200 - h140201 - SPI bytes_to_output reg
 *   h140202 - h140203 - SPI bytes_to_receive reg
 *   h140204 - h140207 - SPI operating reg
 *   h140208 - h1403FF - undefined (actually, repetitions of SPI regs)
 *   h140400 - h17FFFF - undefined (actually, repetitions of SPI memory & regs)
 *   h180000 - h1BFFFF - UART (not implemented yet)
 *   h1C0000 - h1C000F - miscellaneous peripherals
 *   h1C000F - h1FFFFF - undefined (actually, repetitions misc. peripherals)
 */
`default_nettype none

`ifndef ROM_WORDS_COUNT
 `ifndef SIMULATION
  `error_ROM_WORDS_COUNT_must_be_defined
; /* Cause syntax error */
 `endif
 `define ROM_WORDS_COUNT "whatever"
`endif

`ifndef FONT_FILE
 `define FONT_FILE "design/font.mem"
`endif

`ifndef EMBEDDED_ROM_FILE
 `define EMBEDDED_ROM_FILE "design/rom.mem"
`endif

module soc
  #(
    parameter FONT_FILE = `FONT_FILE,
    parameter ROM_WORDS_COUNT = `ROM_WORDS_COUNT,
    parameter ROM_FILE = `EMBEDDED_ROM_FILE
    )
   (
    input wire 	       clock_100mhz,

    output wire [17:0] sram_addr,
    inout wire [15:0]  sram_io,

    output wire        sram_cs_n,
    output wire        sram_oe_n,
    output wire        sram_we_n,

    output wire        vga_hs,
    output wire        vga_vs,
    output wire [2:0]  vga_red,
    output wire [2:0]  vga_green,
    output wire [2:0]  vga_blue,

    output wire        spi_sdo,
    input wire 	       spi_sdi,
    output wire        spi_sck,
    output wire        spi_ss_n,

    input wire 	       button1,
    input wire 	       button2,

    output wire        led1,
    output wire        led2
   );

   /*
    * Master 0 is stack machine's wrapped data interface.
    * Master 1 is stack machine's instructions interface.
    */
   wire        M0_ACK_I,   M1_ACK_I;
   wire [19:0] M0_ADR_O,   M1_ADR_O;
   wire [15:0] M0_DAT_I,   M1_DAT_I;
   wire [15:0] M0_DAT_O,   M1_DAT_O;
   wire        M0_STB_O,   M1_STB_O;
   wire        M0_CYC_O,   M1_CYC_O;
   wire        M0_WE_O,    M1_WE_O;
   wire        M0_STALL_I, M1_STALL_I;

   wire 	       S0_ACK_O,   S1_ACK_O,   S2_ACK_O,
		       S3_ACK_O,   S4_ACK_O,   S5_ACK_O;
   wire [17:0] 	       S0_ADR_I,   S1_ADR_I;
   wire [16:0] 	       S2_ADR_I,   S3_ADR_I,   S4_ADR_I,   S5_ADR_I;
   wire [15:0] 	       S0_DAT_I,   S1_DAT_I,   S2_DAT_I,
		       S3_DAT_I,   S4_DAT_I,   S5_DAT_I;
   wire [15:0] 	       S0_DAT_O,   S1_DAT_O,   S2_DAT_O,
		       S3_DAT_O,   S4_DAT_O,   S5_DAT_O;
   wire 	       S0_STB_I,   S1_STB_I,   S2_STB_I,
		       S3_STB_I,   S4_STB_I,   S5_STB_I;
   wire 	       S0_WE_I,    S1_WE_I,    S2_WE_I,
		       S3_WE_I,    S4_WE_I,    S5_WE_I;
   wire 	       S0_STALL_O, S1_STALL_O, S2_STALL_O,
		       S3_STALL_O, S4_STALL_O, S5_STALL_O;

   wire 	       CLK;
   wire 	       RST;

   /* Non-wishbone */
   wire 	       M_finished;
   wire 	       clock_25mhz;


   wrapped_stack_machine stack_machine
     (
      .CLK_I(CLK),
      .RST_I(RST),

      /* Instruction reading interface */
      .I_ACK_I(M1_ACK_I),
      .I_ADR_O(M1_ADR_O),
      .I_DAT_I(M1_DAT_I),
      .I_DAT_O(M1_DAT_O),
      .I_STB_O(M1_STB_O),
      .I_CYC_O(M1_CYC_O),
      .I_WE_O(M1_WE_O),
      .I_STALL_I(M1_STALL_I),

      /* Data interface */
      .D_ACK_I(M0_ACK_I),
      .D_ADR_O(M0_ADR_O),
      .D_DAT_I(M0_DAT_I),
      .D_DAT_O(M0_DAT_O),
      .D_STB_O(M0_STB_O),
      .D_CYC_O(M0_CYC_O),
      .D_WE_O(M0_WE_O),
      .D_STALL_I(M0_STALL_I),

      .finished(M_finished)
      );

   embedded_bram_slave
     #(
       .MEMORY_BLOCKS(2),
       .WORDS_TO_INITIALIZE(ROM_WORDS_COUNT),
       .INITIAL_CONTENTS_FILE(ROM_FILE)
       ) slave0
       (
	.ACK_O(S0_ACK_O),
      	.CLK_I(CLK),
	.ADR_I(S0_ADR_I[8:0]),
	.DAT_I(S0_DAT_I),
	.DAT_O(S0_DAT_O),
      	.RST_I(RST),
      	.STB_I(S0_STB_I),
      	.WE_I(S0_WE_I),
	.STALL_O(S0_STALL_O)
	);

   sram_slave slave1
     (
      .sram_addr(sram_addr),
      .sram_io(sram_io),
      .sram_cs_n(sram_cs_n),
      .sram_oe_n(sram_oe_n),
      .sram_we_n(sram_we_n),

      .ACK_O(S1_ACK_O),
      .CLK_I(CLK),
      .ADR_I(S1_ADR_I),
      .DAT_I(S1_DAT_I),
      .DAT_O(S1_DAT_O),
      .RST_I(RST),
      .STB_I(S1_STB_I),
      .WE_I(S1_WE_I),
      .STALL_O(S1_STALL_O)
      );

   vga
     #(
       .FONT_FILE(FONT_FILE)
       ) slave2
       (
	.ACK_O(S2_ACK_O),
      	.CLK_I(CLK),
	.ADR_I(S2_ADR_I[10:0]),
	.DAT_I(S2_DAT_I),
	.DAT_O(S2_DAT_O),
      	.RST_I(RST),
      	.STB_I(S2_STB_I),
      	.WE_I(S2_WE_I),
	.STALL_O(S2_STALL_O),

	/* Non-wishbone */
	.clock_25mhz(clock_25mhz),
	.h_sync(vga_hs),
	.v_sync(vga_vs),
	.red(vga_red),
	.green(vga_green),
	.blue(vga_blue)
	);

   spi_slave
     #(
       .MEMORY_BLOCKS(1)
       ) slave3
       (
	.ACK_O(S3_ACK_O),
      	.CLK_I(CLK),
	.ADR_I(S3_ADR_I[8:0]),
	.DAT_I(S3_DAT_I),
	.DAT_O(S3_DAT_O),
      	.RST_I(RST),
      	.STB_I(S3_STB_I),
      	.WE_I(S3_WE_I),
	.STALL_O(S3_STALL_O),

	/* Non-wishbone */
	.sdo(spi_sdo),
	.sdi(spi_sdi),
	.sck(spi_sck),
	.ss_n(spi_ss_n)
	);

   miscellaneous_slave slave5
     (
      .ACK_O(S5_ACK_O),
      .CLK_I(CLK),
      .ADR_I(S5_ADR_I[2:0]),
      .DAT_I(S5_DAT_I),
      .DAT_O(S5_DAT_O),
      .RST_I(RST),
      .STB_I(S5_STB_I),
      .WE_I(S5_WE_I),
      .STALL_O(S5_STALL_O),

      /* Non-wishbone */
      .button2(button2),
      .led2(led2)
      );

   /* Slaves 4 will be UART controller but for now - it's omitted */
   assign S4_ACK_O = 1;
   assign S4_DAT_O = 0;
   assign S4_STALL_O = 0;

   intercon intercon
     (
      .CLK(CLK),
      .RST(RST),

      .S0_ACK_O(S0_ACK_O),
      .S0_ADR_I(S0_ADR_I),
      .S0_DAT_I(S0_DAT_I),
      .S0_DAT_O(S0_DAT_O),
      .S0_STB_I(S0_STB_I),
      .S0_WE_I(S0_WE_I),
      .S0_STALL_O(S0_STALL_O),

      .S1_ACK_O(S1_ACK_O),
      .S1_ADR_I(S1_ADR_I),
      .S1_DAT_I(S1_DAT_I),
      .S1_DAT_O(S1_DAT_O),
      .S1_STB_I(S1_STB_I),
      .S1_WE_I(S1_WE_I),
      .S1_STALL_O(S1_STALL_O),

      .S2_ACK_O(S2_ACK_O),
      .S2_ADR_I(S2_ADR_I),
      .S2_DAT_I(S2_DAT_I),
      .S2_DAT_O(S2_DAT_O),
      .S2_STB_I(S2_STB_I),
      .S2_WE_I(S2_WE_I),
      .S2_STALL_O(S2_STALL_O),

      .S3_ACK_O(S3_ACK_O),
      .S3_ADR_I(S3_ADR_I),
      .S3_DAT_I(S3_DAT_I),
      .S3_DAT_O(S3_DAT_O),
      .S3_STB_I(S3_STB_I),
      .S3_WE_I(S3_WE_I),
      .S3_STALL_O(S3_STALL_O),

      .S4_ACK_O(S4_ACK_O),
      .S4_ADR_I(S4_ADR_I),
      .S4_DAT_I(S4_DAT_I),
      .S4_DAT_O(S4_DAT_O),
      .S4_STB_I(S4_STB_I),
      .S4_WE_I(S4_WE_I),
      .S4_STALL_O(S4_STALL_O),

      .S5_ACK_O(S5_ACK_O),
      .S5_ADR_I(S5_ADR_I),
      .S5_DAT_I(S5_DAT_I),
      .S5_DAT_O(S5_DAT_O),
      .S5_STB_I(S5_STB_I),
      .S5_WE_I(S5_WE_I),
      .S5_STALL_O(S5_STALL_O),

      .M0_ACK_I(M0_ACK_I),
      .M0_ADR_O(M0_ADR_O),
      .M0_DAT_I(M0_DAT_I),
      .M0_DAT_O(M0_DAT_O),
      .M0_STB_O(M0_STB_O),
      .M0_CYC_O(M0_CYC_O),
      .M0_WE_O(M0_WE_O),
      .M0_STALL_I(M0_STALL_I),

      .M1_ACK_I(M1_ACK_I),
      .M1_ADR_O(M1_ADR_O),
      .M1_DAT_I(M1_DAT_I),
      .M1_DAT_O(M1_DAT_O),
      .M1_STB_O(M1_STB_O),
      .M1_CYC_O(M1_CYC_O),
      .M1_WE_O(M1_WE_O),
      .M1_STALL_I(M1_STALL_I)
      );

   reg [2:0] 	       clock_divider;
   always @ (posedge clock_100mhz)
     clock_divider <= clock_divider + 1;

   assign clock_25mhz = clock_divider[1];
   /* We might later raise it up to even as high as 50 MHz */
   assign CLK = clock_divider[2];

   reg 		       reset;
   always @ (posedge CLK)
     reset <= !button1;

   assign RST = reset;

   assign led1 = !M_finished;

`ifdef SIMULATION
   /* avoid undefined values */
   initial begin
      clock_divider <= 0;
      reset <= 1;
   end
`endif
endmodule // soc