OpenCores
URL https://opencores.org/ocsvn/rf6809/rf6809/trunk

Subversion Repositories rf6809

[/] [rf6809/] [trunk/] [rtl/] [CmodA7/] [SocCS02.sv] - Rev 16

Compare with Previous | Blame | View Log

// ============================================================================
//        __
//   \\__/ o\    (C) 2019-2022  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//                                                                          
// ============================================================================
//
`define DEBUG           1'b1
//`define SIM           1'b1

module SocCS02(sysclk, btn,
        pio2, pio3,
        led, led0_r, led0_g, led0_b,
        uart_rxd_out, uart_txd_in,
        MemAdr, MemDB, RamOEn, RamWEn, RamCEn);
input sysclk;
input [1:0] btn;
inout tri [6:0] pio2;
inout tri [22:0] pio3;
output [1:0] led;
output reg led0_r;
output reg led0_g;
output reg led0_b;
output uart_rxd_out;
input uart_txd_in;
output reg [18:0] MemAdr;
inout tri [7:0] MemDB;
output reg RamOEn;
output reg RamWEn;
output reg RamCEn;

parameter SYNC = 8'hFF;
parameter HIGH = 1'b1;
parameter LOW = 1'b0;


assign pio2 = 7'bz;
assign pio3 = 23'bz;

// -----------------------------------------------------------------------------
// Signals and registers
// -----------------------------------------------------------------------------
wire xrst;                                      // external reset (push button)
wire rst;                                               // internal reset
wire clk120;
wire clk80;
wire clk40;
wire clk;                                               // system clock (50MHz)
wire clk14p7;                           // uart clock 14.746 MHz
wire clk20;                                     // 20MHz for wall clock time
wire cpuclk;
wire locked;                            // clock generation is locked
wire [1:0] btn_db;      // debounced button output

reg irq;
wire vpa;
wire cyc;                                               // cpu cycle is active
wire stb;                                               // cpu transfer strobe
reg ack;                                                // cpu transfer acknowledge
wire we;                                                // cpu write cycle
wire [23:0] adr;                // cpu address
reg [11:0] dat_i;               // cpu data input
wire [11:0] dat_o;      // cpu data output
reg [11:0] dati;                // memory data input

wire cs_rom0, cs_rom1;
wire cs_io;
wire cs_mem;
wire cs_via;
wire cs_sema;
wire ack_rom0, ack_rom1;
wire ack_mem;
wire uart_irq, via_irq;
wire ack_uart, ack_via, ack_sema, rnd_ack;
wire xal;
wire [11:0] rom0_dato;
wire [11:0] rom1_dato;
wire [11:0] uart_dato;
wire [11:0] via_dato;
wire [11:0] mem_dato;
wire [11:0] sema_dato;
wire [11:0] rnd_dato;
wire [11:0] pa;
wire [11:0] pa_i;
wire [11:0] pa_o;
wire badram;
wire t3_if;

// -----------------------------------------------------------------------------
// Clock generation
// -----------------------------------------------------------------------------

cs02clkgen ucg1
(
  // Clock out ports
  .clk120(clk120),
  .clk80(clk80),
  .clk40(clk40),
  .clk14p7(clk14p7),
  .clk20(clk20),
  // Status and control signals
  .reset(xrst),
  .locked(locked),
 // Clock in ports
  .clk_in1(sysclk)
);

assign rst = !locked;
assign irq = uart_irq|via_irq;
assign clk = clk40;
assign cpuclk = clk40;

// -----------------------------------------------------------------------------
// Circuit select logic
// -----------------------------------------------------------------------------
// Memory map
//
// 000000       +---------------+
//              |               |
//              |   Ram 256kB   | (12 bits wide)
//                |               |
// 040000       +---------------+
//                |    unused     |
// E00000 +---------------+
//                  |     I/O       |
// EFFFFF       +---------------+
//                              |                unused                 |
// FF8000       +---------------+
//        |     ROM       |
// FFFFFF       +---------------+
//
// I/O Map
//
// E3010x       +---------------+
//        |    Uart6551   |
//        +---------------+
//
// E3060x       +---------------+
//        |     PRNG      |
//        +---------------+
//
// E600xx +---------------+
//        |    VIA6522    |
//        +---------------+
//
// EF0xxx       +---------------+
//        |  semaphores   |
//        +---------------+
//
// -----------------------------------------------------------------------------

assign cs_rom0 = adr[23:14]==10'h3FF;   // $FFFExxxxx to $FFFFxxxxx
assign cs_rom1 = adr[23:14]==10'h3FE;   // $FFFExxxxx to $FFFFxxxxx
//assign cs_basrom = cyc && stb && adr[31:16]==16'b1111_1111_1111_1101; // $FFFCxxxx to $FFFFxxxx
assign cs_mem = adr[23:20]==4'h0;
assign cs_via = adr[23:8]==16'hE600;
assign cs_uart = adr[23:8]==16'hE301;
assign cs_sema = adr[23:16]==8'hEF;
reg cs_rnd;
always_comb cs_rnd = adr[23:8]==16'hE306;               // PRNG random number generator

// -----------------------------------------------------------------------------
// Input debouncing
// Pressing both buttons at the same time resets the system.
// -----------------------------------------------------------------------------

BtnDebounce udbu (sysclk, btn[0], btn_db[0]);
BtnDebounce udbd (sysclk, btn[1], btn_db[1]);

`ifdef SIM
assign xrst = btn[0];// & btn[1];
`else
assign xrst = btn_db[0] & btn_db[1];
`endif

assign pa_i[8] = btn_db[0];
assign pa_i[9] = btn_db[1];

// -----------------------------------------------------------------------------
// clock divider
// Used to pulse width modulate (PWM) the led signals to reduce the brightness.
// -----------------------------------------------------------------------------

reg [31:0] dvd;
always @(posedge clk)
if (rst)
        dvd <= 32'd1;
else begin
        if (dvd==32'd50000000)
                dvd <= 32'd1;
        else
                dvd <= dvd + 32'd1;
end

// -----------------------------------------------------------------------------
// LED output
// -----------------------------------------------------------------------------

assign led[0] = pa_o[3] & ~dvd[26] & dvd[12];
assign led[1] = pa_o[4] & dvd[12];

assign led0_r = ~irq;   // pa[0]
assign led0_g = ~cyc;   // pa[1]
assign led0_b = ~(pa_o[2] & dvd[12]);   // PWM 50% at about 12kHz.

// -----------------------------------------------------------------------------
// Memory interface
// -----------------------------------------------------------------------------

wire MemT;
wire [7:0] MemDBo;

cs02memInterface umi1
(
        .rst_i(rst),
        .clk_i(clk40),
        .cpuclk_i(cpuclk),
        .cs_i(cs_mem),
        .cyc_i(cyc),
        .stb_i(stb),
        .ack_o(ack_mem),
        .we_i(we),
        .adr_i(adr),
        .dat_i(dat_o),
        .dat_o(mem_dato), 
        .RamCEn(RamCEn),
        .RamWEn(RamWEn),
        .RamOEn(RamOEn),
        .MemAdr(MemAdr),
        .MemDBo(MemDBo),
        .MemDBi(MemDB)
);
assign MemDB = {8{RamWEn}} ? 8'bz : MemDBo;
//assign mem_dato = cs_mem ? mem_dato1 : 32'd0;

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

random  uprg1
(
        .rst_i(rst),
        .clk_i(cpuclk),
        .cs_i(cs_rnd),
        .cyc_i(cyc),
        .stb_i(stb),
        .ack_o(rnd_ack),
        .we_i(we),
        .adr_i(adr[3:0]),
        .dat_i(dat_o),
        .dat_o(rnd_dato)
);

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

semamem usema1
(
        .rst_i(rst),
  .clk_i(cpuclk),
  .cs_i(cs_sema),
  .cyc_i(cyc),
  .stb_i(stb),
  .ack_o(ack_sema),
  .we_i(we),
  .adr_i(adr[12:0]),
  .dat_i(dat_o),
  .dat_o(sema_dato)
);

scratchmem uscr2
(
  .rst_i(rst),
  .clk_i(cpuclk),
  .cti_i(3'b000),
  .bok_o(),
  .cs_i(cs_rom0),
  .cyc_i(cyc),
  .stb_i(stb),
  .ack_o(ack_rom0),
  .we_i(we),
  .adr_i(adr[13:0]),
  .dat_i(dat_o),
  .dat_o(rom0_dato)
`ifdef SIM
  ,.sp(24'h0)
`else
        ,.sp(24'h0)
`endif
);
demomem uscr2a
(
  .rst_i(rst),
  .clk_i(cpuclk),
  .cti_i(3'b000),
  .bok_o(),
  .cs_i(cs_rom1),
  .cyc_i(cyc),
  .stb_i(stb),
  .ack_o(ack_rom1),
  .we_i(we),
  .adr_i(adr[13:0]),
  .dat_i(dat_o),
  .dat_o(rom1_dato)
`ifdef SIM
  ,.sp(24'h0)
`else
        ,.sp(24'h0)
`endif
);

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

via6522_x12 uvia1
(
        .rst_i(rst),
        .clk_i(cpuclk),
        .wc_clk_i(clk40),
        .irq_o(via_irq),
        .cs_i(cs_via),
        .cyc_i(cyc),
        .stb_i(stb),
        .ack_o(ack_via),
        .we_i(we),
        .adr_i(adr[6:0]),
        .dat_i(dat_o),
        .dat_o(via_dato), 
        .pa_i(pa_i),
        .pa_o(pa_o),
        .pa_t(),
        .pb_i(),
        .pb_o(),
        .pb_t(),
        .ca1(),
        .ca2_i(),
        .ca2_o(),
        .ca2_t(),
        .cb1_i(),
        .cb1_o(),
        .cb1_t(),
        .cb2_i(),
        .cb2_o(),
        .cb2_t(),
        .t1_if(),
        .t2_if(),
        .t3_if(t3_if)
);

// -----------------------------------------------------------------------------
// UART
// -----------------------------------------------------------------------------

uart6551_x12 #(.CLK_FREQ(40)) uuart1
(
        .rst_i(rst),
        .clk_i(clk40),
        .cs_i(cs_uart),
        .irq_o(uart_irq),
        .cyc_i(cyc),
        .stb_i(stb),
        .ack_o(ack_uart),
        .we_i(we),
        .adr_i(adr[3:0]),
        .dat_i(dat_o),
        .dat_o(uart_dato),
        .cts_ni(1'b0),
        .rts_no(),
        .dsr_ni(1'b0),
        .dcd_ni(1'b0),
        .dtr_no(),
        .ri_ni(1'b1),
        .rxd_i(uart_txd_in),
        .txd_o(uart_rxd_out),
        .data_present(),
        .rxDRQ_o(),
        .txDRQ_o(),
        .xclk_i(clk20),
        .RxC_i(1'b0)
);

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

wire err;

BusError ube1
(
        .rst_i(rst),
        .clk_i(cpuclk),
        .cyc_i(cyc),
        .ack_i(ack),
        .stb_i(stb),
        .adr_i(adr),
        .err_o(err)
);

// -----------------------------------------------------------------------------
// CPU
// -----------------------------------------------------------------------------

always @(posedge cpuclk)
        ack <= ack_rom0|ack_rom1|ack_mem|ack_via|ack_uart|ack_sema|rnd_ack;

always @(posedge cpuclk)
        dat_i <= rom0_dato|rom1_dato|mem_dato|via_dato|uart_dato|sema_dato|rnd_dato;

rf6809 ucpu1
(
        .id(6'h20),
        .rst_i(rst),
        .clk_i(cpuclk),
        .halt_i(1'b0),
        .nmi_i(1'b0),
        .irq_i(via_irq),
        .firq_i(1'b0),
        .vec_i(24'h0),
        .ba_o(),
        .bs_o(),
        .lic_o(),
        .tsc_i(1'b0),
        .rty_i(1'b0),
        .bte_o(),
        .cti_o(cti),
        .bl_o(),
        .lock_o(),
        .cyc_o(cyc),
        .stb_o(stb),
        .we_o(we),
        .ack_i(ack),
        .aack_i(ack),
        .atag_i(adr[3:0]),
        .adr_o(adr),
        .dat_i(dat_i),
        .dat_o(dat_o),
        .state()
);


CS02_ILA uila1 (
        .clk(clk80), // input wire clk


        .probe0(ucpu1.pc), // input wire [31:0]  probe0  
        .probe1(ucpu1.dat_i), // input wire [31:0]  probe1 
        .probe2(ucpu1.cyc_o), // input wire [0:0]  probe2 
        .probe3(ucpu1.we_o), // input wire [0:0]  probe3 
        .probe4(ucpu1.adr_o), // input wire [31:0]  probe4 
        .probe5(MemDB), // input wire [31:0]  probe5
        .probe6({umi1.ack_o,RamCEn,RamOEn,RamWEn,umi1.state}),
        .probe7(MemAdr)
//      .probe6({ucpu1.to_done,ucpu1.state,ucpu1.crs,ucpu1.regset})
);


endmodule

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.