mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-05-02 06:36:12 +00:00
417 lines
13 KiB
Verilog
417 lines
13 KiB
Verilog
// PlusToo_top for the MIST FPGA board
|
|
|
|
module plusToo_top(
|
|
// clock inputs
|
|
input wire [ 2-1:0] CLOCK_27, // 27 MHz
|
|
// LED outputs
|
|
output wire LED, // LED Yellow
|
|
// UART
|
|
output wire UART_TX, // UART Transmitter (MIDI out)
|
|
input wire UART_RX, // UART Receiver (MIDI in)
|
|
// VGA
|
|
output wire VGA_HS, // VGA H_SYNC
|
|
output wire VGA_VS, // VGA V_SYNC
|
|
output wire [ 6-1:0] VGA_R, // VGA Red[5:0]
|
|
output wire [ 6-1:0] VGA_G, // VGA Green[5:0]
|
|
output wire [ 6-1:0] VGA_B, // VGA Blue[5:0]
|
|
// SDRAM
|
|
inout wire [ 16-1:0] SDRAM_DQ, // SDRAM Data bus 16 Bits
|
|
output wire [ 13-1:0] SDRAM_A, // SDRAM Address bus 13 Bits
|
|
output wire SDRAM_DQML, // SDRAM Low-byte Data Mask
|
|
output wire SDRAM_DQMH, // SDRAM High-byte Data Mask
|
|
output wire SDRAM_nWE, // SDRAM Write Enable
|
|
output wire SDRAM_nCAS, // SDRAM Column Address Strobe
|
|
output wire SDRAM_nRAS, // SDRAM Row Address Strobe
|
|
output wire SDRAM_nCS, // SDRAM Chip Select
|
|
output wire [ 2-1:0] SDRAM_BA, // SDRAM Bank Address
|
|
output wire SDRAM_CLK, // SDRAM Clock
|
|
output wire SDRAM_CKE, // SDRAM Clock Enable
|
|
// MINIMIG specific
|
|
output wire AUDIO_L, // sigma-delta DAC output left
|
|
output wire AUDIO_R, // sigma-delta DAC output right
|
|
// SPI
|
|
inout wire SPI_DO,
|
|
input wire SPI_DI,
|
|
input wire SPI_SCK,
|
|
input wire SPI_SS2, // fpga
|
|
input wire SPI_SS3, // OSD
|
|
input wire SPI_SS4, // "sniff" mode
|
|
input wire CONF_DATA0 // SPI_SS for user_io
|
|
);
|
|
|
|
// include the OSD into the video data path
|
|
osd #(10,0,2) osd (
|
|
.pclk ( clk32 ),
|
|
|
|
// spi for OSD
|
|
.sdi ( SPI_DI ),
|
|
.sck ( SPI_SCK ),
|
|
.ss ( SPI_SS3 ),
|
|
|
|
.red_in ( { red, 2'b00 } ),
|
|
.green_in ( { green, 2'b00 } ),
|
|
.blue_in ( { blue, 2'b00 } ),
|
|
.hs_in ( hsync ),
|
|
.vs_in ( vsync ),
|
|
|
|
.red_out ( VGA_R ),
|
|
.green_out ( VGA_G ),
|
|
.blue_out ( VGA_B ),
|
|
.hs_out ( VGA_HS ),
|
|
.vs_out ( VGA_VS )
|
|
);
|
|
|
|
// -------------------------------------------------------------------------
|
|
// ------------------------------ data_io ----------------------------------
|
|
// -------------------------------------------------------------------------
|
|
|
|
// include ROM download helper
|
|
wire dio_download;
|
|
wire dio_write;
|
|
wire [23:0] dio_addr;
|
|
wire [4:0] dio_index;
|
|
wire [15:0] dio_data;
|
|
|
|
// disk image is being stored right after os rom at word offset 0x10000
|
|
wire [20:0] dio_a = (dio_index == 0)?dio_addr[20:0]:{21'h10000 + dio_addr[20:0]};
|
|
|
|
data_io data_io (
|
|
// io controller spi interface
|
|
.sck ( SPI_SCK ),
|
|
.ss ( SPI_SS2 ),
|
|
.sdi ( SPI_DI ),
|
|
|
|
.downloading ( dio_download ), // signal indicating an active rom download
|
|
.index ( dio_index ), // 0=rom download, 1=disk image
|
|
|
|
// external ram interface
|
|
.clk ( clk8 ),
|
|
.wr ( dio_write ),
|
|
.addr ( dio_addr ),
|
|
.data ( dio_data )
|
|
);
|
|
|
|
// keys and switches are dummies as the mist doesn't have any ...
|
|
wire [9:0] sw = 10'd0;
|
|
wire [3:0] key = 4'd0;
|
|
|
|
// the macs video signals. To be fed into the MiSTs OSD overlay and then
|
|
// send to the VGA
|
|
wire hsync;
|
|
wire vsync;
|
|
wire [3:0] red;
|
|
wire [3:0] green;
|
|
wire [3:0] blue;
|
|
|
|
// various debug signals for the DE1/DE2. These don't exist on the MIST
|
|
// and will be optimized away ...
|
|
wire [6:0] hex0;
|
|
wire [6:0] hex1;
|
|
wire [6:0] hex2;
|
|
wire [6:0] hex3;
|
|
wire [7:0] ledg;
|
|
|
|
// ps2 interface for mouse, to be mapped into user_io
|
|
wire mouseClk;
|
|
wire mouseData;
|
|
|
|
// NO REAL LOGIC SHOULD GO IN THIS MODULE!
|
|
// It may not exist in the hand-built Plus Too.
|
|
// Only interconnections and interfaces specific to the dev board should go here
|
|
|
|
// synthesize a 32.5 MHz clock
|
|
wire clk32;
|
|
wire clk128;
|
|
wire pll_locked;
|
|
clock325MHz cs0(
|
|
.inclk0 ( CLOCK_27[0] ),
|
|
.c0 ( clk32 ),
|
|
.c1 ( clk128 ),
|
|
.c2 ( SDRAM_CLK ),
|
|
.locked ( pll_locked )
|
|
);
|
|
|
|
// generate ~16kHz for ps2
|
|
wire ps2_clk = ps2_clk_div[10];
|
|
reg [10:0] ps2_clk_div;
|
|
always @(posedge clk8)
|
|
ps2_clk_div <= ps2_clk_div + 11'd1;
|
|
|
|
// set the real-world inputs to sane defaults
|
|
localparam keyClk = 1'b0,
|
|
keyData = 1'b0,
|
|
serialIn = 1'b0,
|
|
interruptButton = 1'b0,
|
|
configROMSize = 1'b1, // 128K ROM
|
|
configRAMSize = 2'b01; // 512K RAM
|
|
|
|
// interconnects
|
|
// CPU
|
|
wire clk8, _cpuReset, _cpuAS, _cpuUDS, _cpuLDS, _cpuRW, _cpuDTACK, cpuDriveData;
|
|
wire [2:0] _cpuIPL;
|
|
wire [7:0] cpuAddrHi;
|
|
wire [23:0] cpuAddr;
|
|
wire [15:0] cpuDataOut;
|
|
|
|
// RAM/ROM
|
|
wire _romCS, _romOE;
|
|
wire _ramCS, _ramOE, _ramWE;
|
|
wire _memoryUDS, _memoryLDS;
|
|
wire videoBusControl;
|
|
wire [21:0] memoryAddr;
|
|
wire [15:0] memoryDataOut;
|
|
wire memoryDriveData;
|
|
wire [15:0] memoryDataInMux;
|
|
|
|
// peripherals
|
|
wire loadSound, loadNormalPixels, loadDebugPixels, pixelOut, _hblank, _vblank;
|
|
wire memoryOverlayOn, selectSCC, selectIWM, selectVIA, selectInterruptVectors;
|
|
wire [15:0] dataControllerDataOut;
|
|
wire dataControllerDriveData;
|
|
|
|
// debug panel
|
|
wire _debugDTACK, driveDebugData, loadPixels, extraRomReadAck;
|
|
wire [15:0] debugDataOut;
|
|
wire [21:0] extraRomReadAddr;
|
|
|
|
// LED debug lights
|
|
assign ledg = { 2'b00, diskInDrive[1], diskInDrive[1], diskInDrive[0], diskInDrive[0], 2'b00 };
|
|
|
|
// convert 1-bit pixel data to 4:4:4 RGB
|
|
// force pixels in debug area to appear green
|
|
assign red[3:0] = _vblank == 1'b0 ? 4'h0 : { pixelOut, pixelOut, pixelOut, pixelOut };
|
|
assign green[3:0] = { pixelOut, pixelOut, pixelOut, pixelOut };
|
|
assign blue[3:0] = _vblank == 1'b0 ? 4'h0 : { pixelOut, pixelOut, pixelOut, pixelOut };
|
|
|
|
// memory-side data input mux
|
|
// In a hand-built system, both RAM and ROM data will be on the same physical pins,
|
|
// making this mux unnecessary
|
|
assign memoryDataInMux = driveDebugData ? debugDataOut :
|
|
sdram_do;
|
|
|
|
// the configuration string is returned to the io controller to allow
|
|
// it to control the menu on the OSD
|
|
parameter CONF_STR = {
|
|
"PLUS_TOO;;",
|
|
"F1,BIN;",
|
|
"T2,Reset"
|
|
};
|
|
|
|
parameter CONF_STR_LEN = 10+7+8;
|
|
|
|
// the status register is controlled by the on screen display (OSD)
|
|
wire [7:0] status;
|
|
wire [1:0] buttons;
|
|
|
|
// include user_io module for arm controller communication
|
|
user_io #(.STRLEN(CONF_STR_LEN)) user_io (
|
|
.conf_str ( CONF_STR ),
|
|
|
|
.SPI_CLK ( SPI_SCK ),
|
|
.SPI_SS_IO ( CONF_DATA0 ),
|
|
.SPI_MISO ( SPI_DO ),
|
|
.SPI_MOSI ( SPI_DI ),
|
|
|
|
.status ( status ),
|
|
.buttons ( buttons ),
|
|
|
|
// ps2 interface
|
|
.ps2_clk ( ps2_clk ),
|
|
.ps2_kbd_clk ( ),
|
|
.ps2_kbd_data ( ),
|
|
.ps2_mouse_clk ( mouseClk ),
|
|
.ps2_mouse_data( mouseData )
|
|
);
|
|
|
|
|
|
debugPanel dp(
|
|
.clk8(clk8),
|
|
.sw(sw),
|
|
.key(key),
|
|
.videoBusControl(videoBusControl),
|
|
.loadNormalPixels(loadNormalPixels),
|
|
.loadDebugPixels(loadDebugPixels),
|
|
.loadPixelsOut(loadPixels),
|
|
._dtackIn(_cpuDTACK),
|
|
.cpuAddrHi(cpuAddrHi),
|
|
.cpuAddr(cpuAddr),
|
|
._cpuRW(_cpuRW),
|
|
._cpuUDS(_cpuUDS),
|
|
._cpuLDS(_cpuLDS),
|
|
.dataControllerDataOut(dataControllerDataOut),
|
|
.cpuDataOut(cpuDataOut),
|
|
.memoryAddr(memoryAddr),
|
|
._dtackOut(_debugDTACK),
|
|
.hex0(hex0),
|
|
.hex1(hex1),
|
|
.hex2(hex2),
|
|
.hex3(hex3),
|
|
.driveDebugData(driveDebugData),
|
|
.debugDataOut(debugDataOut),
|
|
.extraRomReadAck(extraRomReadAck));
|
|
|
|
wire [2:0] _debugIPL = sw[0] == 1'b1 ? 3'b111 : _cpuIPL; // suppress interrupts when sw0 on
|
|
|
|
TG68 m68k(
|
|
.clk(clk8),
|
|
.reset(_cpuReset),
|
|
.clkena_in(1'b1),
|
|
.data_in(dataControllerDataOut),
|
|
.IPL(_debugIPL),
|
|
.dtack(_debugDTACK),
|
|
.addr({cpuAddrHi, cpuAddr}),
|
|
.data_out(cpuDataOut),
|
|
.as(_cpuAS),
|
|
.uds(_cpuUDS),
|
|
.lds(_cpuLDS),
|
|
.rw(_cpuRW),
|
|
.drive_data(cpuDriveData));
|
|
|
|
addrController_top ac0(
|
|
.clk8(clk8),
|
|
.cpuAddr(cpuAddr),
|
|
._cpuAS(_cpuAS),
|
|
._cpuUDS(_cpuUDS),
|
|
._cpuLDS(_cpuLDS),
|
|
._cpuRW(_cpuRW),
|
|
._cpuDTACK(_cpuDTACK),
|
|
.configROMSize(configROMSize),
|
|
.configRAMSize(configRAMSize),
|
|
.memoryAddr(memoryAddr),
|
|
._memoryUDS(_memoryUDS),
|
|
._memoryLDS(_memoryLDS),
|
|
._romCS(_romCS),
|
|
._romOE(_romOE),
|
|
._ramCS(_ramCS),
|
|
._ramOE(_ramOE),
|
|
._ramWE(_ramWE),
|
|
.videoBusControl(videoBusControl),
|
|
.selectSCC(selectSCC),
|
|
.selectIWM(selectIWM),
|
|
.selectVIA(selectVIA),
|
|
.selectInterruptVectors(selectInterruptVectors),
|
|
.hsync(hsync),
|
|
.vsync(vsync),
|
|
._hblank(_hblank),
|
|
._vblank(_vblank),
|
|
.loadNormalPixels(loadNormalPixels),
|
|
.loadDebugPixels(loadDebugPixels),
|
|
.loadSound(loadSound),
|
|
.memoryOverlayOn(memoryOverlayOn),
|
|
|
|
.extraRomReadAddr(extraRomReadAddr),
|
|
.extraRomReadAck(extraRomReadAck));
|
|
|
|
wire [1:0] diskInDrive;
|
|
|
|
// addional ~8ms delay in reset
|
|
wire n_reset = (rst_cnt == 0);
|
|
reg [15:0] rst_cnt;
|
|
always @(posedge clk8) begin
|
|
// various source can reset the mac
|
|
if(!pll_locked || status[0] || status[2] || buttons[1] || dio_download)
|
|
rst_cnt <= 16'd65535;
|
|
else if(rst_cnt != 0)
|
|
rst_cnt <= rst_cnt - 16'd1;
|
|
end
|
|
|
|
dataController_top dc0(
|
|
.clk32(clk32),
|
|
.clk8out(clk8),
|
|
.clk8(clk8),
|
|
._systemReset(n_reset),
|
|
._cpuReset(_cpuReset),
|
|
._cpuIPL(_cpuIPL),
|
|
._cpuUDS(_cpuUDS),
|
|
._cpuLDS(_cpuLDS),
|
|
._cpuRW(_cpuRW),
|
|
.cpuDataIn(cpuDataOut),
|
|
.cpuDataOut(dataControllerDataOut),
|
|
.cpuDriveData(dataControllerDriveData),
|
|
.cpuAddrRegHi(cpuAddr[12:9]),
|
|
.cpuAddrRegLo(cpuAddr[2:1]),
|
|
.selectSCC(selectSCC),
|
|
.selectIWM(selectIWM),
|
|
.selectVIA(selectVIA),
|
|
.selectInterruptVectors(selectInterruptVectors),
|
|
.videoBusControl(videoBusControl),
|
|
.memoryDataOut(memoryDataOut),
|
|
.memoryDataIn(memoryDataInMux),
|
|
.memoryDriveData(memoryDriveData),
|
|
.keyClk(keyClk),
|
|
.keyData(keyData),
|
|
.mouseClk(mouseClk),
|
|
.mouseData(mouseData),
|
|
.serialIn(serialIn),
|
|
._hblank(_hblank),
|
|
._vblank(_vblank),
|
|
.pixelOut(pixelOut),
|
|
.loadPixels(loadPixels),
|
|
.loadSound(loadSound),
|
|
.interruptButton(1'b1),
|
|
.memoryOverlayOn(memoryOverlayOn),
|
|
.insertDisk( 2'b01 ),
|
|
.diskInDrive(diskInDrive),
|
|
|
|
.extraRomReadAddr(extraRomReadAddr),
|
|
.extraRomReadAck(extraRomReadAck));
|
|
|
|
// ram/rom maps directly into 68k address space
|
|
|
|
// multiplex sdram between mac and the rom downloader
|
|
// 4MB RAM
|
|
// wire [24:0] sdram_addr = dio_download?{ 3'b001, dio_a[20:0] }:{ 2'b00, ~_romOE, memoryAddr[21:1] };
|
|
|
|
wire [20:0] memoryAddrEx =
|
|
extraRomReadAck?memoryAddr[21:1]: // full access to floppy image
|
|
// memoryAddr[21:1]; // CPU access not masked giving 4MB ram
|
|
{ 3'b000, memoryAddr[18:1]} ; // CPU access masked for 512k ram
|
|
|
|
wire [24:0] sdram_addr = dio_download?{ 4'b0001, dio_a[20:0] }:{ 3'b000, ~_romOE, memoryAddrEx };
|
|
|
|
wire [15:0] sdram_din = dio_download?dio_data:memoryDataOut;
|
|
wire [1:0] sdram_ds = dio_download?2'b11:{ !_memoryUDS, !_memoryLDS };
|
|
wire sdram_we = dio_download?dio_write:!_ramWE;
|
|
wire sdram_oe = dio_download?1'b0:(!_ramOE || !_romOE);
|
|
|
|
|
|
// during rom/disk download ffff is returned so the screen is black during download
|
|
// "extra rom" is used to hold the disk image. It's expected to be byte wide and
|
|
// we thus need to properly demultiplex the word returned from sdram in that case
|
|
wire [15:0] extra_rom_data_demux = memoryAddr[0]?
|
|
{sdram_out[7:0],sdram_out[7:0]}:{sdram_out[15:8],sdram_out[15:8]};
|
|
wire [15:0] sdram_do = dio_download?16'hffff:
|
|
extraRomReadAck?extra_rom_data_demux:
|
|
sdram_out;
|
|
wire [15:0] sdram_out;
|
|
|
|
assign SDRAM_CKE = 1'b1;
|
|
|
|
sdram sdram (
|
|
// interface to the MT48LC16M16 chip
|
|
.sd_data ( SDRAM_DQ ),
|
|
.sd_addr ( SDRAM_A ),
|
|
.sd_dqm ( {SDRAM_DQMH, SDRAM_DQML} ),
|
|
.sd_cs ( SDRAM_nCS ),
|
|
.sd_ba ( SDRAM_BA ),
|
|
.sd_we ( SDRAM_nWE ),
|
|
.sd_ras ( SDRAM_nRAS ),
|
|
.sd_cas ( SDRAM_nCAS ),
|
|
|
|
// system interface
|
|
.clk_128 ( clk128 ),
|
|
.clk_8 ( clk8 ),
|
|
.init ( !pll_locked ),
|
|
|
|
// cpu/chipset interface
|
|
// map rom to sdram word address $200000 - $20ffff
|
|
.din ( sdram_din ),
|
|
.addr ( sdram_addr ),
|
|
.ds ( sdram_ds ),
|
|
.we ( sdram_we ),
|
|
.oe ( sdram_oe ),
|
|
.dout ( sdram_out )
|
|
);
|
|
|
|
endmodule
|