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

Subversion Repositories next186mp3

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /next186mp3/trunk
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/HW/soundwave.v
0,0 → 1,116
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//
// This file is part of the Next186 Soc PC project
// http://opencores.org/project,next186
//
// Filename: sound_gen.v
// Description: Part of the Next186 SoC PC project,
// stereo 2x16bit pulse density modulated sound generator
// 44100 samples/sec
// Disney Sound Source and Covox Speech compatible
// Version 1.0
// Creation date: Jan2015
//
// Author: Nicolae Dumitrache
// e-mail: ndumitrache@opencores.org
//
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2012 Nicolae Dumitrache
//
// This source file may be used and distributed without
// restriction provided that this copyright statement is not
// removed from the file and that any derivative work contains
// the original copyright notice and the associated disclaimer.
//
// This source file is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation;
// either version 2.1 of the License, or (at your option) any
// later version.
//
// This source is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General
// Public License along with this source; if not, download it
// from http://www.opencores.org/lgpl.shtml
//
//////////////////////////////////////////////////////////////////////////////////
// Additional Comments:
//
// byte write: both channels are the same (Covox emulation), the 8bit sample value is shifted by 8, the channel selector is reset to LEFT
// word write: LEFT first, the queue is updated only after RIGHT value is written
// sample rate: 44100Hz
//////////////////////////////////////////////////////////////////////////////////
module soundwave(
input CLK,
input CLK44100x256,
input [15:0]data,
input we,
input word,
output full, // when not full, write max 2x1152 16bit samples
output dss_full,
output reg AUDIO_L,
output reg AUDIO_R
);
 
reg [31:0]wdata;
reg lr = 1'b0;
reg [2:0]write = 3'b000;
wire [31:0]sample;
reg [31:0]lval = 0;
reg [31:0]rval = 0;
reg [8:0]clkdiv = 0;
wire lsign = lval[31:16] < sample[15:0];
wire rsign = rval[31:16] < sample[31:16];
wire empty;
assign dss_full = !empty; // Disney sound source queue full
sndfifo sndfifo_inst
(
.wr_clk(CLK), // input wr_clk
.rd_clk(CLK44100x256), // input rd_clk
.din(wdata), // input [31 : 0] din
.wr_en(|write), // input wr_en
.rd_en(clkdiv[8]), // input rd_en
.dout(sample), // output [31 : 0] dout
// .full(full), // output full
// .empty(empty), // output empty
.prog_full(full), // output prog_full
.prog_empty(empty)
);
 
always @(posedge CLK44100x256) begin
clkdiv[8:0] <= clkdiv[7:0] + 1'b1;
lval <= lval - lval[31:7] + (lsign << 25);
AUDIO_L <= lsign;
 
rval <= rval - rval[31:7] + (rsign << 25);
AUDIO_R <= rsign;
end
 
 
always @(posedge CLK) begin
if(we)
if(word) begin
lr <= !lr;
write <= {2'b00, lr};
if(lr) wdata[31:16] <= {!data[15], data[14:0]};
else wdata[15:0] <= {!data[15], data[14:0]};
end else begin
lr <= 1'b0; // left
write <= 3'b110;
wdata <= {1'b0, data[7:0], 8'b00000000, data[7:0], 7'b0000000};
end
else write <= write - |write;
end
 
 
endmodule
/HW/vga.v
0,0 → 1,357
//////////////////////////////////////////////////////////////////////////////////
//
// This file is part of the Next186 Soc PC project
// http://opencores.org/project,next186
//
// Filename: vga.v
// Description: Part of the Next186 SoC PC project, VGA module
// customized VGA, only modes 3 (25x80x256 text), 13h (320x200x256 graphic)
// and VESA 101h (640x480x256) implemented
// Version 1.0
// Creation date: Jan2012
//
// Author: Nicolae Dumitrache
// e-mail: ndumitrache@opencores.org
//
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2012 Nicolae Dumitrache
//
// This source file may be used and distributed without
// restriction provided that this copyright statement is not
// removed from the file and that any derivative work contains
// the original copyright notice and the associated disclaimer.
//
// This source file is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation;
// either version 2.1 of the License, or (at your option) any
// later version.
//
// This source is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General
// Public License along with this source; if not, download it
// from http://www.opencores.org/lgpl.shtml
//
///////////////////////////////////////////////////////////////////////////////////
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
 
`timescale 1 ns / 1 ps
 
module VGA_SG
(
input wire [9:0] tc_hsblnk,
input wire [9:0] tc_hssync,
input wire [9:0] tc_hesync,
input wire [9:0] tc_heblnk,
 
output reg [9:0] hcount = 0,
output reg hsync,
output reg hblnk = 0,
 
input wire [9:0] tc_vsblnk,
input wire [9:0] tc_vssync,
input wire [9:0] tc_vesync,
input wire [9:0] tc_veblnk,
 
output reg [9:0] vcount = 0,
output reg vsync,
output reg vblnk = 0,
 
input wire clk,
input wire ce
);
 
//******************************************************************//
// This logic describes a 10-bit horizontal position counter. //
//******************************************************************//
always @(posedge clk)
if(ce) begin
if(hcount >= tc_heblnk) begin
hcount <= 0;
hblnk <= 0;
end else begin
hcount <= hcount + 1;
hblnk <= (hcount >= tc_hsblnk);
end
hsync <= (hcount >= tc_hssync) && (hcount < tc_hesync);
end
//******************************************************************//
// This logic describes a 10-bit vertical position counter. //
//******************************************************************//
always @(posedge clk)
if(ce && hcount == tc_heblnk) begin
if (vcount >= tc_veblnk) begin
vcount <= 0;
vblnk <= 0;
end else begin
vcount <= vcount + 1;
vblnk <= (vcount >= tc_vsblnk);
end
vsync <= (vcount >= tc_vssync) && (vcount < tc_vesync);
end
 
//******************************************************************//
// This is the logic for the horizontal outputs. Active video is //
// always started when the horizontal count is zero. Example: //
//
//
// tc_hsblnk = 03 //
// tc_hssync = 07 //
// tc_hesync = 11 //
// tc_heblnk = 15 (htotal) //
// //
// hcount 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 //
// hsync ________________________------------____________ //
// hblnk ____________------------------------------------ //
// //
// hsync time = (tc_hesync - tc_hssync) pixels //
// hblnk time = (tc_heblnk - tc_hsblnk) pixels //
// active time = (tc_hsblnk + 1) pixels //
// //
//******************************************************************//
 
//******************************************************************//
// This is the logic for the vertical outputs. Active video is //
// always started when the vertical count is zero. Example: //
// //
// tc_vsblnk = 03 //
// tc_vssync = 07 //
// tc_vesync = 11 //
// tc_veblnk = 15 (vtotal) //
// //
// vcount 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 //
// vsync ________________________------------____________ //
// vblnk ____________------------------------------------ //
// //
// vsync time = (tc_vesync - tc_vssync) lines //
// vblnk time = (tc_veblnk - tc_vsblnk) lines //
// active time = (tc_vsblnk + 1) lines //
// //
//******************************************************************//
 
 
endmodule
 
 
module VGA_DAC(
input CE,
input WR,
input [3:0]addr,
input [7:0]din,
output [7:0]dout,
input CLK,
input VGA_CLK,
input [7:0]vga_addr,
input setindex,
output [17:0]color,
output reg vgatext = 1,
output reg vga400 = 1,
output reg vgaflash = 0,
output reg half = 0,
output reg [3:0]hrzpan = 0
);
reg [7:0]mask = 8'hff;
reg [9:0]index = 0;
reg mode = 0;
reg [1:0]a0mode = 0;
reg a0data = 0;
wire [7:0]pal_dout;
wire [31:0]pal_out;
wire addr6 = addr == 6;
wire addr7 = addr == 7;
wire addr8 = addr == 8;
wire addr9 = addr == 9;
wire addr0 = addr == 0;
 
DAC_SRAM vga_dac
(
.clka(CLK), // input clka
.wea(CE & WR & addr9), // input [0 : 0] wea
.addra(index), // input [9 : 0] addra
.dina(din), // input [7 : 0] dina
.douta(pal_dout), // output [7 : 0] douta
.clkb(VGA_CLK), // input clkb
.web(1'b0), // input [0 : 0] web
.addrb(vga_addr & mask), // input [7 : 0] addrb
.dinb(32'h00000000), // input [31 : 0] dinb
.doutb(pal_out) // output [31 : 0] doutb
);
assign color = {pal_out[21:16], pal_out[13:8], pal_out[5:0]};
assign dout = addr6 ? mask : addr7 ? {6'bxxxxxx, mode, mode} : addr8 ? index[9:2] : pal_dout;
always @(posedge CLK) begin
if(setindex) a0data <= 0;
else if(CE && addr0 && WR) a0data <= ~a0data;
if(CE) begin
if(addr0) begin
if(WR) begin
if(a0data) case(a0mode)
2'b01: {vga400, half, vgaflash, vgatext} <= {din[6], din[4:3], ~din[0]};
2'b10: hrzpan <= din[3:0];
endcase else case(din[4:0])
5'h10: a0mode <= 2'b01;
5'h13: a0mode <= 2'b10;
default: a0mode <= 2'b00;
endcase
end
end
if(addr6 && WR) mask <= din;
if(addr7 | addr8) begin
if(WR) index <= {din, 2'b00};
mode <= addr8;
end else if(addr9) index <= index + (index[1:0] == 2'b10 ? 2 : 1);
end
end
 
endmodule
 
 
 
module VGA_CRT(
input CE,
input WR,
input WORD,
input [15:0]din,
input addr,
output reg [7:0]dout,
input CLK,
output reg oncursor,
output wire [11:0]cursorpos,
output wire [15:0]scraddr,
output reg v240 = 1'b0,
output reg [7:0]offset = 8'h28
);
reg [7:0]crtc[3:0];
reg [4:0]index = 0;
assign cursorpos = {crtc[2][3:0], crtc[3]};
assign scraddr = {crtc[0], crtc[1]};
always @(posedge CLK) begin
if(CE && WR) begin
if(addr) begin
if(index == 5'h6) v240 <= ~din[7];
if(index == 5'ha) oncursor <= din[5];
if(index >= 5'hc && index <= 5'hf) crtc[index[1:0]] <= din[7:0];
if(index == 5'h13) offset <= din[7:0];
end else begin
if(WORD) begin
if(din[4:0] == 5'h6) v240 <= ~din[15];
if(din[4:0] == 5'ha) oncursor <= din[13];
if(din[4:0] >= 5'hc && din[4:0] <= 5'hf) crtc[din[1:0]] <= din[15:8];
if(din[4:0] == 5'h13) offset <= din[15:8];
end
index <= din[4:0];
end
end
dout <= crtc[index[1:0]];
end
endmodule
 
 
module VGA_SC(
input CE,
input WR,
input WORD,
input [15:0]din,
output reg [7:0]dout,
input addr,
input CLK,
output reg planarreq,
output reg[3:0]wplane
);
reg [2:0]index = 0;
always @(posedge CLK) begin
if(CE && WR) begin
if(addr) begin
if(index == 2) wplane <= din[3:0];
if(index == 4) planarreq <= ~din[3];
end else begin
if(WORD) begin
if(din[2:0] == 2) wplane <= din[11:8];
if(din[2:0] == 4) planarreq <= ~din[11];
end
index <= din[2:0];
end
end
dout <= {4'b0000, index == 2 ? wplane : {~planarreq, 3'b000}};
end
endmodule
 
 
module VGA_GC(
input CE,
input WR,
input WORD,
input [15:0]din,
output reg [7:0]dout,
input addr,
input CLK,
output reg [1:0]rplane = 2'b00,
output reg[7:0]bitmask = 8'b11111111,
output reg [2:0]rwmode = 3'b000,
output reg [3:0]setres = 4'b0000,
output reg [3:0]enable_setres = 4'b0000,
output reg [1:0]logop = 2'b00,
output reg [3:0]color_compare,
output reg [3:0]color_dont_care
);
reg [3:0]index = 0;
always @(posedge CLK) begin
if(CE && WR) begin
if(addr) begin
case(index)
0: setres <= din[3:0];
1: enable_setres <= din[3:0];
2: color_compare <= din[3:0];
3: logop <= din[4:3];
4: rplane <= din[1:0];
5: rwmode <= {din[3], din[1:0]};
7: color_dont_care <= din[3:0];
8: bitmask <= din[7:0];
endcase
end else begin
if(WORD) case(din[3:0])
0: setres <= din[11:8];
1: enable_setres <= din[11:8];
2: color_compare <= din[11:8];
3: logop <= din[12:11];
4: rplane <= din[9:8];
5: rwmode <= {din[11], din[9:8]};
7: color_dont_care <= din[11:8];
8: bitmask <= din[15:8];
endcase
index <= din[3:0];
end
end
case(index)
0: dout[3:0] <= setres;
1: dout[3:0] <= enable_setres;
2: dout[3:0] <= color_compare;
3: dout[4:3] <= logop;
4: dout[1:0] <= rplane;
5: dout[3:0] <= {rwmode[2], 1'bx, rwmode[1:0]};
7: dout[3:0] <= color_dont_care;
8: dout[7:0] <= bitmask;
endcase
end
endmodule
 
/HW/unit186.v
0,0 → 1,185
//////////////////////////////////////////////////////////////////////////////////
//
// This file is part of the Next186 Soc PC project
// http://opencores.org/project,next186
//
// Filename: unit186.v
// Description: Part of the Next186 SoC PC project, 80186 unit (CPU + BIU)
// Version 1.0
// Creation date: Mar2012
//
// Author: Nicolae Dumitrache
// e-mail: ndumitrache@opencores.org
//
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2012 Nicolae Dumitrache
//
// This source file may be used and distributed without
// restriction provided that this copyright statement is not
// removed from the file and that any derivative work contains
// the original copyright notice and the associated disclaimer.
//
// This source file is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation;
// either version 2.1 of the License, or (at your option) any
// later version.
//
// This source is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General
// Public License along with this source; if not, download it
// from http://www.opencores.org/lgpl.shtml
//
///////////////////////////////////////////////////////////////////////////////////
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
 
`timescale 1ns / 1ps
 
module unit186(
input [15:0]INPORT,
input [31:0]DIN,
output [15:0]CPU_DOUT,
output [31:0]DOUT,
output [20:0]ADDR,
output [3:0]WMASK,
output [15:0]PORT_ADDR,
input CLK,
input CE,
output CPU_CE,
output CE_186,
input INTR,
input NMI,
input RST,
output INTA,
output LOCK,
output HALT,
output MREQ,
output IORQ,
output WR,
output WORD,
input PLANAR,
input [3:0]VGA_WPLANE,
input [1:0]VGA_RPLANE,
input [7:0]VGA_BITMASK,
input [2:0]VGA_RWMODE,
input [3:0]VGA_SETRES,
input [3:0]VGA_ENABLE_SETRES,
input [1:0]VGA_LOGOP,
input [3:0]VGA_COLOR_COMPARE,
input [3:0]VGA_COLOR_DONT_CARE
);
 
wire [15:0] CPU_DIN;
wire [20:0] CPU_IADDR;
wire [20:0] CPU_ADDR;
wire [47:0] CPU_INSTR;
wire CPU_MREQ; // CPU memory request
wire IFETCH;
wire FLUSH;
wire [2:0]ISIZE;
wire [3:0]RAM_WMASK;
wire [31:0]RAM_DOUT;
wire VGAWORD;
wire [7:0]N_COMPARE = ((DIN[31:24] ^ {8{VGA_COLOR_COMPARE[3]}}) & {8{VGA_COLOR_DONT_CARE[3]}}) |
((DIN[23:16] ^ {8{VGA_COLOR_COMPARE[2]}}) & {8{VGA_COLOR_DONT_CARE[2]}}) |
((DIN[15:8] ^ {8{VGA_COLOR_COMPARE[1]}}) & {8{VGA_COLOR_DONT_CARE[1]}}) |
((DIN[7:0] ^ {8{VGA_COLOR_COMPARE[0]}}) & {8{VGA_COLOR_DONT_CARE[0]}});
wire [7:0]SEL_RDATA = VGA_RWMODE[2] ? ~N_COMPARE : (DIN >> {VGA_RPLANE, 3'b000});
reg [31:0]VGA_LATCH;
wire VGA_SEL = PLANAR && (CPU_ADDR[19:16] == 4'ha);
wire RAM_RD;
wire RAM_WR;
reg s_RAM_RD;
assign ADDR[1:0] = CPU_ADDR[1:0];
assign CPU_CE = CE_186 & CE;
assign PORT_ADDR = CPU_ADDR[15:0];
assign WMASK = (VGA_SEL & RAM_WR) ? VGA_WPLANE : RAM_WMASK;
wire [7:0]VGA_BITMASK1 = VGA_SEL ? (VGA_RWMODE[1:0] == 2'b01 ? 8'h00 : VGA_RWMODE[1:0] == 2'b11 ? (VGA_BITMASK & RAM_DOUT[7:0]) : VGA_BITMASK) : 8'hff;
wire [3:0]EXPAND = VGA_SEL ? VGA_RWMODE[1:0] == 2'b00 ? VGA_ENABLE_SETRES : 4'b1111 : 4'b0000;
wire [3:0]EXPAND_BIT = VGA_RWMODE[1:0] == 2'b10 ? RAM_DOUT[3:0] : VGA_SETRES;
wire [31:0]RAM_DOUT1 = {EXPAND[3] ? {8{EXPAND_BIT[3]}} : RAM_DOUT[31:24], EXPAND[2] ? {8{EXPAND_BIT[2]}} : RAM_DOUT[23:16],
EXPAND[1] ? {8{EXPAND_BIT[1]}} : RAM_DOUT[15:8], EXPAND[0] ? {8{EXPAND_BIT[0]}} : RAM_DOUT[7:0]};
reg [31:0]RAM_DOUT2;
assign DOUT = ({4{VGA_BITMASK1}} & RAM_DOUT2) | ({4{~VGA_BITMASK1}} & VGA_LATCH);
always @(*)
if(VGA_SEL)
case(VGA_LOGOP)
2'b00: RAM_DOUT2 = RAM_DOUT1;
2'b01: RAM_DOUT2 = RAM_DOUT1 & VGA_LATCH;
2'b10: RAM_DOUT2 = RAM_DOUT1 | VGA_LATCH;
2'b11: RAM_DOUT2 = RAM_DOUT1 ^ VGA_LATCH;
endcase
else RAM_DOUT2 = RAM_DOUT1;
 
Next186_CPU cpu
(
.ADDR(CPU_ADDR),
.DIN(IORQ | INTA ? INPORT : CPU_DIN),
.DOUT(CPU_DOUT),
.CLK(CLK),
.CE(CPU_CE),
.INTR(INTR),
.NMI(NMI),
.RST(RST),
.MREQ(CPU_MREQ),
.IORQ(IORQ),
.INTA(INTA),
.WR(WR),
.WORD(WORD),
.LOCK(LOCK),
.IADDR(CPU_IADDR),
.INSTR(CPU_INSTR),
.IFETCH(IFETCH),
.FLUSH(FLUSH),
.ISIZE(ISIZE),
.HALT(HALT)
);
 
BIU186_32bSync_2T_DelayRead BIU
(
.CLK(CLK),
.INSTR(CPU_INSTR),
.ISIZE(ISIZE),
.IFETCH(IFETCH),
.FLUSH(FLUSH),
.MREQ(CPU_MREQ),
.WR(WR),
.WORD(WORD),
.ADDR(VGA_SEL ? {2'b11, CPU_ADDR[15], ~CPU_ADDR[15], CPU_ADDR[14:0], WORD, WORD} : CPU_ADDR),
.IADDR(CPU_IADDR),
.CE186(CE_186),
.RAM_DIN(s_RAM_RD ? {4{SEL_RDATA}} : DIN),
.RAM_DOUT(RAM_DOUT),
.RAM_ADDR(ADDR[20:2]),
.RAM_MREQ(MREQ),
.RAM_WMASK(RAM_WMASK),
.DOUT(CPU_DIN),
.DIN(CPU_DOUT),
.CE(CE),
.data_bound(VGAWORD),
.WSEL(VGA_SEL ? {VGAWORD, VGAWORD} : {~CPU_ADDR[0], CPU_ADDR[0]}),
.RAM_RD(RAM_RD),
.RAM_WR(RAM_WR)
);
always @(posedge CLK) if(CE) begin
s_RAM_RD <= VGA_SEL & RAM_RD;
if(s_RAM_RD) VGA_LATCH <= DIN;
end
endmodule
/HW/papiliopro_next186soc_141_78.2_from_149_81_mapchanneldensityparstandardct21_31.26.bit Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
HW/papiliopro_next186soc_141_78.2_from_149_81_mapchanneldensityparstandardct21_31.26.bit Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: HW/PapilioProMain.v =================================================================== --- HW/PapilioProMain.v (nonexistent) +++ HW/PapilioProMain.v (revision 2) @@ -0,0 +1,112 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 15:25:31 11/20/2014 +// Design Name: +// Module Name: PapilioProMain +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + +module PapilioPro_Next186Soc + ( + input CLK_32MHZ, + output [5:0]VGA_R, + output [5:0]VGA_G, + output [5:0]VGA_B, + output VGA_HSYNC, + output VGA_VSYNC, + output SDRAM_CLK, + output SDRAM_CKE, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nCS, + output SDRAM_nWE, + output [1:0]SDRAM_BA, + output [12:0]SDRAM_ADDR, + inout [15:0]SDRAM_DATA, + output SDRAM_DQML, + output SDRAM_DQMH, + output [7:0]LED, + input BTN_SOUTH, + input BTN_WEST, + input RX, + output TX, + output AUDIO_L, + output AUDIO_R, + inout PS2CLKA, + inout PS2CLKB, + inout PS2DATA, + inout PS2DATB, + output SD_nCS, + output SD_DI, + output SD_CK, + input SD_DO + ); + + assign SDRAM_CKE = 1'b1; + wire SDR_CLK; + + ODDR2 #( + .DDR_ALIGNMENT("NONE"), // Sets output alignment to "NONE", "C0" or "C1" + .INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1 + .SRTYPE("SYNC") // Specifies "SYNC" or "ASYNC" set/reset + ) ODDR2_inst + ( + .Q(SDRAM_CLK), // 1-bit DDR output data + .C0(SDR_CLK), // 1-bit clock input + .C1(!SDR_CLK), // 1-bit clock input + .CE(1'b1), // 1-bit clock enable input + .D0(1'b1), // 1-bit data input (associated with C0) + .D1(1'b0), // 1-bit data input (associated with C1) + .R(1'b0), // 1-bit reset input + .S(1'b0) // 1-bit set input + ); + + + system sys_inst + ( + .CLK_32MHZ(CLK_32MHZ), + .VGA_R(VGA_R), + .VGA_G(VGA_G), + .VGA_B(VGA_B), + .VGA_HSYNC(VGA_HSYNC), + .VGA_VSYNC(VGA_VSYNC), + .sdr_CLK_out(SDR_CLK), + .sdr_n_CS_WE_RAS_CAS({SDRAM_nCS, SDRAM_nWE, SDRAM_nRAS, SDRAM_nCAS}), + .sdr_BA(SDRAM_BA), + .sdr_ADDR(SDRAM_ADDR), + .sdr_DATA(SDRAM_DATA), + .sdr_DQM({SDRAM_DQMH, SDRAM_DQML}), + .LED(LED), + .BTN_RESET(BTN_SOUTH), + .BTN_NMI(BTN_WEST), + .RS232_DCE_RXD(RX), + .RS232_DCE_TXD(TX), + .SD_n_CS(SD_nCS), + .SD_DI(SD_DI), + .SD_CK(SD_CK), + .SD_DO(SD_DO), + .AUD_L(AUDIO_L), + .AUD_R(AUDIO_R), + .PS2_CLK1(PS2CLKA), + .PS2_CLK2(PS2CLKB), + .PS2_DATA1(PS2DATA), + .PS2_DATA2(PS2DATB), + .RS232_HOST_RXD(1'b0) +// .RS232_HOST_TXD(host_tx_o), +// .RS232_HOST_RST(host_reset) + ); + +endmodule Index: HW/Cache_bootload.coe =================================================================== --- HW/Cache_bootload.coe (nonexistent) +++ HW/Cache_bootload.coe (revision 2) @@ -0,0 +1,21 @@ +memory_initialization_radix = 16; +memory_initialization_vector = +c88cfcfa, c08ed88e, 00bcd08e, e7c033fc, e70bb080, e70fb08b, e634b08f, e6c03243, e840e640, c0850161, d08b3a74, c106eac1, 10b90ae0, 83c12b00, db3300da, e8515250, +5949010b, 1c75585a, 8301c083, c38100d2, e8e20200, 00003e81, 0875654e, 00023e81, 70747478, b003c0ba, 08b0ee10, 03d4baee, 42ee0ab0, 4aee20b0, 42ee0cb0, 4aee00b0, +42ee0db0, 68ee00b0, 3307b800, 07d0b9ff, abf3c033, b803c8ba, 42ee0101, eeee2ab0, beff33ee, abacfe0d, 75c084ac, 8a40b7fa, 75cffe07, 0100befa, 8a0034e8, 002fe8fc, +2ae8dc8a, 46248800, 33f7754b, ead48ee4, f0000100, 8bfce8be, 0007b9fb, 00bfa4f3, b9f633e0, e3ff1000, 00eaa5f3, b4ffff00, 03daba80, ecfa52b9, 7202e8c0, 0240e4fa, + +e840e4e8, c0ec0008, dcd002e8, e981f573, 40e40a5b, 40e4e838, b0c3f875, ee01b4ff, fb73c003, e8acc3ed, fae2fff3, ffebe8c3, e2472588, e2e8c3f8, 0006b9ff, 33ffe7e8, +ffd7e8f6, 80057446, f574fffc, c28a50c3, 5251b250, dabaf48b, ef01b403, ff0544c6, 83ffd6e8, e40a06c4, d2e81675, fefc80ff, 02b50e75, b4e8fb8b, ff9fe8ff, 41ff9ce8, +e8efc033, bac3ff95, 0ab903da, ff8be800, 01b4fbe2, fe5dbeef, feff9ee8, be6575cc, 91e8fe63, 75ccfeff, 2b04b15b, e8fc8be1, 5858ff7b, 75aafc80, fe75be4b, e8ff77e8, +6fbeff59, ff71e8fe, ed74ccfe, e8fe7bbe, 04b1ff64, fc8be12b, 58ff52e8, 745840a8, fe69be23, 0aff4fe8, e81975e4, fc80ff51, b11175fe, 8be12b12, ff31e8fc, 86f64d8b, + +e78b41cd, e8efc033, c18bff11, 4f4942c3, 6f6e2053, 72702074, 6e657365, 6e6f2074, 43445320, 20647261, 7473616c, 424b3820, 6177202c, 6e697469, 6e6f2067, 32535220, +28203233, 32353131, 70623030, 66202c73, 3a303030, 29303031, 2e2e2e20, 00004000, 48950000, aa010000, 00004987, 69ff0000, 00000040, 000077ff, 7aff0000, 00000000, +000000ff, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, +00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, + +00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, +00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, +00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, +00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00fc00ea, 000000f0, 00000000, 00000000 Index: HW/BPC3011-Papilio_Pro-MegaWing.ucf =================================================================== --- HW/BPC3011-Papilio_Pro-MegaWing.ucf (nonexistent) +++ HW/BPC3011-Papilio_Pro-MegaWing.ucf (revision 2) @@ -0,0 +1,127 @@ +# Main board wing pin [] to FPGA pin Pxx map +# -------C------- -------B------- -------A------- +# [GND] [C00] P114 [GND] [B00] P99 P100 [A15] +# [2V5] [C01] P115 [2V5] [B01] P97 P98 [A14] +# [3V3] [C02] P116 [3V3] [B02] P92 P93 [A13] +# [5V0] [C03] P117 [5V0] [B03] P87 P88 [A12] +# [C04] P118 [B04] P84 P85 [A11] [5V0] +# [C05] P119 [B05] P82 P83 [A10] [3V3] +# [C06] P120 [B06] P80 P81 [A09] [2V5] +# [C07] P121 [B07] P78 P79 [A08] [GND] +# [GND] [C08] P123 [GND] [B08] P74 P75 [A07] +# [2V5] [C09] P124 [2V5] [B09] P95 P67 [A06] +# [3V3] [C10] P126 [3V3] [B10] P62 P66 [A05] +# [5V0] [C11] P127 [5V0] [B11] P59 P61 [A04] +# [C12] P131 [B12] P57 P58 [A03] [5V0] +# [C13] P132 [B13] P55 P56 [A02] [3V3] +# [C14] P133 [B14] P50 P51 [A01] [2V5] +# [C15] P134 [B15] P47 P48 [A00] [GND] + +## Prohibit the automatic placement of pins that are connected to VCC or GND for configuration. +CONFIG PROHIBIT=P144; +CONFIG PROHIBIT=P69; +CONFIG PROHIBIT=P60; + +NET CLK_32MHZ LOC="P94" | IOSTANDARD = LVTTL | PERIOD=31.26ns; +NET RX LOC="P101" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; # RX +NET TX LOC="P105" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW | PULLUP; # TX + +NET SDRAM_ADDR(0) LOC="P140" | IOSTANDARD=LVTTL; # SDRAM_ADDR0 +NET SDRAM_ADDR(1) LOC="P139" | IOSTANDARD=LVTTL; # SDRAM_ADDR1 +NET SDRAM_ADDR(2) LOC="P138" | IOSTANDARD=LVTTL; # SDRAM_ADDR2 +NET SDRAM_ADDR(3) LOC="P137" | IOSTANDARD=LVTTL; # SDRAM_ADDR3 +NET SDRAM_ADDR(4) LOC="P46" | IOSTANDARD=LVTTL; # SDRAM_ADDR4 +NET SDRAM_ADDR(5) LOC="P45" | IOSTANDARD=LVTTL; # SDRAM_ADDR5 +NET SDRAM_ADDR(6) LOC="P44" | IOSTANDARD=LVTTL; # SDRAM_ADDR6 +NET SDRAM_ADDR(7) LOC="P43" | IOSTANDARD=LVTTL; # SDRAM_ADDR7 +NET SDRAM_ADDR(8) LOC="P41" | IOSTANDARD=LVTTL; # SDRAM_ADDR8 +NET SDRAM_ADDR(9) LOC="P40" | IOSTANDARD=LVTTL; # SDRAM_ADDR9 +NET SDRAM_ADDR(10) LOC="P141" | IOSTANDARD=LVTTL; # SDRAM_ADDR10 +NET SDRAM_ADDR(11) LOC="P35" | IOSTANDARD=LVTTL; # SDRAM_ADDR11 +NET SDRAM_ADDR(12) LOC="P34" | IOSTANDARD=LVTTL; # SDRAM_ADDR12 +NET SDRAM_DATA(0) LOC="P9" | IOSTANDARD=LVTTL; # SDRAM_DATA0 +NET SDRAM_DATA(1) LOC="P10" | IOSTANDARD=LVTTL; # SDRAM_DATA1 +NET SDRAM_DATA(2) LOC="P11" | IOSTANDARD=LVTTL; # SDRAM_DATA2 +NET SDRAM_DATA(3) LOC="P12" | IOSTANDARD=LVTTL; # SDRAM_DATA3 +NET SDRAM_DATA(4) LOC="P14" | IOSTANDARD=LVTTL; # SDRAM_DATA4 +NET SDRAM_DATA(5) LOC="P15" | IOSTANDARD=LVTTL; # SDRAM_DATA5 +NET SDRAM_DATA(6) LOC="P16" | IOSTANDARD=LVTTL; # SDRAM_DATA6 +NET SDRAM_DATA(7) LOC="P8" | IOSTANDARD=LVTTL; # SDRAM_DATA7 +NET SDRAM_DATA(8) LOC="P21" | IOSTANDARD=LVTTL; # SDRAM_DATA8 +NET SDRAM_DATA(9) LOC="P22" | IOSTANDARD=LVTTL; # SDRAM_DATA9 +NET SDRAM_DATA(10) LOC="P23" | IOSTANDARD=LVTTL; # SDRAM_DATA10 +NET SDRAM_DATA(11) LOC="P24" | IOSTANDARD=LVTTL; # SDRAM_DATA11 +NET SDRAM_DATA(12) LOC="P26" | IOSTANDARD=LVTTL; # SDRAM_DATA12 +NET SDRAM_DATA(13) LOC="P27" | IOSTANDARD=LVTTL; # SDRAM_DATA13 +NET SDRAM_DATA(14) LOC="P29" | IOSTANDARD=LVTTL; # SDRAM_DATA14 +NET SDRAM_DATA(15) LOC="P30" | IOSTANDARD=LVTTL; # SDRAM_DATA15 +NET SDRAM_DQML LOC="P7" | IOSTANDARD=LVTTL; # SDRAM_DQML +NET SDRAM_DQMH LOC="P17" | IOSTANDARD=LVTTL; # SDRAM_DQMH +NET SDRAM_BA(0) LOC="P143" | IOSTANDARD=LVTTL; # SDRAM_BA0 +NET SDRAM_BA(1) LOC="P142" | IOSTANDARD=LVTTL; # SDRAM_BA1 +NET SDRAM_nWE LOC="P6" | IOSTANDARD=LVTTL; # SDRAM_nWE +NET SDRAM_nCAS LOC="P5" | IOSTANDARD=LVTTL; # SDRAM_nCAS +NET SDRAM_nRAS LOC="P2" | IOSTANDARD=LVTTL; # SDRAM_nRAS +NET SDRAM_nCS LOC="P1" | IOSTANDARD=LVTTL; # SDRAM_CS +NET SDRAM_CLK LOC="P32" | IOSTANDARD=LVTTL; # SDRAM_CLK +NET SDRAM_CKE LOC="P33" | IOSTANDARD=LVTTL; # SDRAM_CKE +#NET JTAG_TMS LOC="P107" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # JTAG_TMS +#NET JTAG_TCK LOC="P109" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # JTAG_TCK +#NET JTAG_TDI LOC="P110" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # JTAG_TDI +#NET JTAG_TDO LOC="P106" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # JTAG_TDO +#NET FLASH_CS LOC="P38" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # FLASH_CS +#NET FLASH_CK LOC="P70" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # FLASH_CK +#NET FLASH_SI LOC="P64" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # FLASH_SI +#NET FLASH_SO LOC="P65" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # FLASH_SO + +NET "VGA_R<5>" LOC = "P121" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #C7 - 0.5K || 10K +NET "VGA_R<4>" LOC = "P120" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #C6 - 1K +NET "VGA_R<3>" LOC = "P119" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #C5 - 2K +NET "VGA_R<2>" LOC = "P118" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #C4 - 4K +NET "VGA_R<1>" LOC = "P133" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #C14 - 8K +NET "VGA_R<0>" LOC = "P131" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #C12 - 16K + +NET "VGA_G<5>" LOC = "P78" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B7 - 0.5K || 10K +NET "VGA_G<4>" LOC = "P80" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B6 - 1K +NET "VGA_G<3>" LOC = "P82" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B5 - 2K +NET "VGA_G<2>" LOC = "P84" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B4 - 4K +NET "VGA_G<1>" LOC = "P55" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B13 - 8K +NET "VGA_G<0>" LOC = "P57" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B12 - 16K + +NET "VGA_B<5>" LOC = "P87" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B3 - 0.5K || 10K +NET "VGA_B<4>" LOC = "P92" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B2 - 1K +NET "VGA_B<3>" LOC = "P97" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B1 - 2K +NET "VGA_B<2>" LOC = "P99" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B0 - 4K +NET "VGA_B<1>" LOC = "P47" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B15 - 8K +NET "VGA_B<0>" LOC = "P50" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #B14 - 16K + +NET "VGA_HSYNC" LOC = "P117" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #C3 - 75 +NET "VGA_VSYNC" LOC = "P116" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; #C2 - 75 + +NET "LED<7>" LOC = "P61" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 | PULLDOWN ; #A4 - 330 +NET "LED<6>" LOC = "P66" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 | PULLDOWN ; #A5 - 330 +NET "LED<5>" LOC = "P67" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 | PULLDOWN ; #A6 - 330 +NET "LED<4>" LOC = "P75" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 | PULLDOWN ; #A7 - 330 +NET "LED<3>" LOC = "P58" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 | PULLDOWN ; #A3 - 330 +NET "LED<2>" LOC = "P48" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 | PULLDOWN ; #A0 - 330 +NET "LED<1>" LOC = "P51" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 | PULLDOWN ; #A1 - 330 +NET "LED<0>" LOC = "P56" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 | PULLDOWN ; #A2 - 330 +#NET "LED1" LOC = "P112"| IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE=8 | PULLUP; # USER LED1 + +#NET "BTN_EAST" LOC = "P59" | IOSTANDARD = LVTTL | PULLDOWN ; #B11 - to + +#NET "BTN_NORTH" LOC = "P95" | IOSTANDARD = LVTTL | PULLDOWN ; #B9 - to + +NET "BTN_SOUTH" LOC = "P62" | IOSTANDARD = LVTTL | PULLDOWN ; #B10 - to + +NET "BTN_WEST" LOC = "P74" | IOSTANDARD = LVTTL | PULLDOWN ; #B8 - to + +#NET "BTN_CENTER" LOC = "P85" | IOSTANDARD = LVTTL | PULLDOWN ; #A11 - to + + +NET "PS2DATA" LOC="P114" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW | PULLUP; # C0 +NET "PS2CLKA" LOC="P115" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW | PULLUP; # C1 +NET "PS2DATB" LOC="P88" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW | PULLUP; # A12 +NET "PS2CLKB" LOC="P93" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW | PULLUP; # A13 +NET "AUDIO_L" LOC="P98" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; # A14 +NET "AUDIO_R" LOC="P100" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; # A15 + +NET "SD_nCS" LOC = "P85" |IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 8 ; #A11 +NET "SD_DO" LOC = "P83" |IOSTANDARD = LVTTL | PULLUP; #A10 +NET "SD_CK" LOC = "P81" |IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 8 ; #A9 +NET "SD_DI" LOC = "P79" |IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 8 ; #A8 Index: HW/DSP32.v =================================================================== --- HW/DSP32.v (nonexistent) +++ HW/DSP32.v (revision 2) @@ -0,0 +1,229 @@ +`timescale 1ns / 1ps + +////////////////////////////////////////////////////////////////////////////////// +// +// This file is part of the Next186 Soc PC project +// http://opencores.org/project,next186 +// +// Filename: DSP32.v +// Description: Part of the Next186 SoC PC project, DSP coprocessor +// Version 1.0 +// Creation date: Jan2015 +// +// Author: Nicolae Dumitrache +// e-mail: ndumitrache@opencores.org +// +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2012 Nicolae Dumitrache +// +// This source file may be used and distributed without +// restriction provided that this copyright statement is not +// removed from the file and that any derivative work contains +// the original copyright notice and the associated disclaimer. +// +// This source file is free software; you can redistribute it +// and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; +// either version 2.1 of the License, or (at your option) any +// later version. +// +// This source is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General +// Public License along with this source; if not, download it +// from http://www.opencores.org/lgpl.shtml +// +/////////////////////////////////////////////////////////////////////////////////// +// Additional Comments: +// +// 8 x 64integers overlapping data windows, over 256 integers +// command: 16'b0c000vvvvvvvvvvv = set r/w pointer - 256 32bit integers, 2048 instructions. c=1 for code write, 0 for data read/write +// command: 16'b10wwwvvvvvvvvvvv = run ip - 2048 instructions, 3 bit data window offset +// +// Instructions: +// D=dest(0..63), S=src(0..63) +// 0 - MOV D,S [mov 0,0 = HALT, mov 8,8..mov 15,15 = set data window, other mov x,x = NOP, CF unaffected] +// 1 - SAR D,n [n[2:0] = shift arythmetic right 1..8, CF <- D[0]] +// 2 - ADD D,S +// 3 - ADC D,S +// 4 - SUB D,S +// 5 - SBB D,S +// 6 - MULH D,S [{D, CF} <- D*S >> 32] +// 7 - MULL D,S [{D, CF} <- D*S] +// 8 - MULM D,S [{D, CF} <- D*S >> 16] +// 9 - TOWORD D,S [D <- {WORD(D), WORD(S)}, CF unaffected] +// 10- SHR D,n [n[2:0] = shift logic right 1..8, CF enters through left, CF <- D[0]] +// 11- AND D, S [CF <- 1] +// 12- OR D, S [CF <- (D | S) != 0] +// 13- XOR D, S [CF <- !CF] +////////////////////////////////////////////////////////////////////////////////// + +module DSP32( + input clk, + input cmd, + input ce, + input wr, + input [15:0]din, + output [15:0]dout, + output reg halt +); + + reg [10:0]rwp = 0; // read/write pointer + reg [10:0]ip = 0; // instruction pointer + reg [2:0]dwin = 0; // data window + reg [2:0]dwin1 = 0; + reg hi = 0; + reg [15:0]lodata; + reg [31:0]res; + reg wcode = 0; + reg CF; // carry flag + reg [2:0]op; + wire [15:0]instr; + reg [15:0]instr1; + reg run = 1'b0; + reg mc; + wire signed [31:0]D; + wire signed [31:0]S; + wire cin = (instr1[14] ^ (CF & instr1[12])); + wire [32:0]sumdiff = D + ({32{instr1[14]}} ^ S) + cin; + wire signed [63:0]mul = D * S; + wire [15:0]S16 = (~|S[31:15] | &S[31:15]) ? S[15:0] : {S[31], {15{!S[31]}}}; + wire [15:0]D16 = (~|D[31:15] | &D[31:15]) ? D[15:0] : {D[31], {15{!D[31]}}}; + wire extwrite = ce && wr && !cmd && hi && !wcode; + + assign ihalt = ~|instr; + + instrmem Code + ( + .clka(clk), // input clka + .wea(ce && !cmd && wcode && wr), // input [0 : 0] wea + .addra(rwp), // input [10 : 0] addra + .dina(din), // input [15 : 0] dina + .clkb(clk), // input clkb + .enb(run || (!ihalt && !extwrite)), + .addrb(ip), // input [10 : 0] addrb + .doutb(instr) // output [15 : 0] doutb + ); + + regs DSRegs + ( + .clk(clk), + .we(!halt || extwrite), + .rd(!extwrite), + .wa(extwrite ? rwp[7:0] : {dwin1 + instr1[11], instr1[10:6]}), + .din(extwrite ? {din, lodata} : res), + .rda({dwin + instr[11], instr[10:6]}), + .D(D), + .rsa({dwin + instr[5], instr[4:0]}), + .S(S), + .rra({rwp[7:0], hi}), + .dout(dout) + ); + + always @(op, S, D, S16, D16, instr1, sumdiff, mul) begin + mc = 1'bx; + case(op) + 0: res = S; + 1: res = $signed({instr1[12] ? D[31] : CF, D[30:0]}) >>> (instr1[2:0] + 1); + 2: res = sumdiff[31:0]; + 3: {res, mc} = {mul, 1'b0} >> (instr1[15] ? 16 : instr1[12] ? 0 : 32); + 4: res = {D16, S16}; + 5: res = S & D; + 6: res = S | D; + 7: res = S ^ D; + endcase + end + + + always @(posedge clk) begin + + if(ce) + if(cmd) begin + if(wr && !din[15]) {hi, wcode, rwp} <= {1'b0, din[14], din[10:0]}; // set rwp + end else begin + hi <= !hi; + lodata <= din; + if(wcode || hi) rwp <= rwp + 1'b1; + end + + if(ce && cmd && wr && din[15]) {run, dwin, ip} <= {1'b1, din[13:0]}; // run + else begin + run <= 1'b0; + if(!extwrite) begin + ip <= ip + 1'b1; + if({instr[15:9], instr[5:3]} == 10'b0000001001) dwin <= instr[2:0]; + dwin1 <= dwin; + end + end + + if(!extwrite) begin // if not write external data + halt <= ihalt; + instr1 <= instr; + + case(instr[15:12]) + 0: op <= 3'b000; // S + 1,10: op <= 3'b001; // SAR, SHR + 2,3,4,5: op <= 3'b010; // adder + 6,7,8: op <= 3'b011; // MULHI, MULLO, MULM + 9: op <= 3'b100; // TOWORD + 11: op <= 3'b101; // AND + 12: op <= 3'b110; // OR + 13: op <= 3'b111; // XOR + default: op <= 3'bxxx; + endcase + + case(op) + 1: CF <= S[0]; + 2: CF <= sumdiff[32] ^ instr1[14]; + 3: CF <= mc; + 5: CF <= 1'b1; // and + 6: CF <= |res; // or + 7: CF <= !CF; // xor + endcase + + end + end + +endmodule + + +module regs( + input clk, + input we, + input rd, + input [7:0]wa, + input [31:0]din, + input [7:0]rda, + output reg [31:0]D, + input [7:0]rsa, + output reg [31:0]S, + input [8:0]rra, + output [15:0]dout +); + + reg [31:0]r[255:0]; + + datamem16 RdRegs + ( + .clka(clk), // input clka + .wea(we), // input [0 : 0] wea + .addra(wa), // input [7 : 0] addra + .dina(din), // input [31 : 0] dina + .clkb(clk), // input clkb + .addrb(rra), // input [8 : 0] addrb + .doutb(dout) // output [15 : 0] doutb); + ); + + always @(posedge clk) begin + if(we) r[wa] <= din; + if(rd) D <= /*(we && rda == wa) ? din :*/ r[rda]; + if(rd) S <= /*(we && rsa == wa) ? din :*/ r[rsa]; + end + +endmodule + Index: HW/PIC_8259.v =================================================================== --- HW/PIC_8259.v (nonexistent) +++ HW/PIC_8259.v (revision 2) @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////////////////// +// +// This file is part of the Next186 Soc PC project +// http://opencores.org/project,next186 +// +// Filename: PIC_8259.v +// Description: Part of the Next186 SoC PC project, PIC controller +// 8259 simplified interrupt controller (only interrupt mask can be read, not IRR or ISR, no EOI required) +// Version 1.0 +// Creation date: May2012 +// +// Author: Nicolae Dumitrache +// e-mail: ndumitrache@opencores.org +// +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2012 Nicolae Dumitrache +// +// This source file may be used and distributed without +// restriction provided that this copyright statement is not +// removed from the file and that any derivative work contains +// the original copyright notice and the associated disclaimer. +// +// This source file is free software; you can redistribute it +// and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; +// either version 2.1 of the License, or (at your option) any +// later version. +// +// This source is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General +// Public License along with this source; if not, download it +// from http://www.opencores.org/lgpl.shtml +// +/////////////////////////////////////////////////////////////////////////////////// +// Additional Comments: +// http://wiki.osdev.org/8259_PIC +////////////////////////////////////////////////////////////////////////////////// + +`timescale 1ns / 1ps + +module PIC_8259( + input CS, + input WR, + input [7:0]din, + output wire [7:0]dout, + output reg [7:0]ivect, + input clk, // cpu CLK + output reg INT = 0, + input IACK, + input [3:0]I // 0:timer, 1:keyboard, 2:RTC, 3:mouse + ); + + reg [3:0]ss_I = 0; + reg [3:0]s_I = 0; + reg [3:0]IMR = 4'b1111; + reg [3:0]IRR = 0; + + assign dout = {3'b000, IMR[3:2], 1'b0, IMR[1:0]}; + + always @ (posedge clk) begin + ss_I <= I; + s_I <= ss_I; + IRR <= (IRR | (~s_I & ss_I)) & ~IMR; // front edge detection + if(~INT) begin + if(IRR[0]) begin //timer + INT <= 1; + ivect <= 8'h08; + IRR[0] <= 0; + end else if(IRR[1]) begin // keyboard + INT <= 1; + ivect <= 8'h09; + IRR[1] <= 0; + end else if(IRR[2]) begin // RTC + INT <= 1; + ivect <= 8'h70; + IRR[2] <= 0; + end else if(IRR[3]) begin // mouse + INT <= 1; + ivect <= 8'h74; + IRR[3] <= 0; + end + end else if(IACK) INT <= 0; // also act as Auto EOI + + if(CS & WR) IMR <= {din[4:3], din[1:0]}; + end + + +endmodule + + Index: HW/timer8253.v =================================================================== --- HW/timer8253.v (nonexistent) +++ HW/timer8253.v (revision 2) @@ -0,0 +1,199 @@ +////////////////////////////////////////////////////////////////////////////////// +// +// This file is part of the Next186 Soc PC project +// http://opencores.org/project,next186 +// +// Filename: timer8253.v +// Description: Part of the Next186 SoC PC project, timer +// 8253 simplified timer (no gate, only counters 0 and 2, no read back command) +// Version 1.0 +// Creation date: May2012 +// +// Author: Nicolae Dumitrache +// e-mail: ndumitrache@opencores.org +// +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2012 Nicolae Dumitrache +// +// This source file may be used and distributed without +// restriction provided that this copyright statement is not +// removed from the file and that any derivative work contains +// the original copyright notice and the associated disclaimer. +// +// This source file is free software; you can redistribute it +// and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; +// either version 2.1 of the License, or (at your option) any +// later version. +// +// This source is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General +// Public License along with this source; if not, download it +// from http://www.opencores.org/lgpl.shtml +// +/////////////////////////////////////////////////////////////////////////////////// +// Additional Comments: +// http://wiki.osdev.org/Programmable_Interval_Timer +////////////////////////////////////////////////////////////////////////////////// + +`timescale 1ns / 1ps + +module timer_8253( + input CS, + input WR, + input [1:0]addr, + input [7:0]din, + output wire [7:0]dout, + input CLK_25, + input clk, // cpu CLK + output out0, + output out2 + ); + + reg [8:0]rclk = 0; // rclk[8] oscillates at 1193181.8181... Hz + reg [1:0]cclk = 0; + + always @(posedge CLK_25) begin + if(rclk[7:0] < 8'd208) rclk <= rclk + 21; + else rclk <= rclk + 57; + end + + always @ (posedge clk) begin + cclk <= {cclk[0], rclk[8]}; + end + + wire a0 = addr == 0; + wire a2 = addr == 2; + wire a3 = addr == 3; + wire cmd0 = a3 && din[7:6] == 0; + wire cmd2 = a3 && din[7:6] == 2; + wire [7:0]dout0; + wire [7:0]dout2; + wire [7:0]mode0; + wire [7:0]mode2; + + counter counter0 ( + .CS(CS && (a0 || cmd0)), + .WR(WR), + .clk(clk), + .cmd(cmd0), + .din(din), + .dout(dout0), + .mode(mode0), + .CE(cclk) + ); + + counter counter2 ( + .CS(CS && (a2 || cmd2)), + .WR(WR), + .clk(clk), + .cmd(cmd2), + .din(din), + .dout(dout2), + .mode(mode2), + .CE(cclk) + ); + + assign out0 = mode0[7]; + assign out2 = mode2[7]; + assign dout = a0 ? dout0 : dout2; + +endmodule + + +module counter( + input CS, + input WR, // write cmd/data + input clk, // CPU clk + input cmd, + input [7:0]din, + output [7:0]dout, + output reg [7:0]mode, // mode[7] = output + input [1:0]CE // count enable + ); + + reg [15:0]count = 0; + reg [15:0]init = 0; + reg [1:0]state = 0; // state[1] = init reg filled + reg strobe = 0; + reg rd = 0; + reg latch = 0; + reg newcmd = 0; + wire c1 = count == 1; + wire c2 = count == 2; + reg CE1 = 0; + + assign dout = mode[5] & (~mode[4] | rd) ? count[15:8] : count[7:0]; + + always @(posedge clk) begin + + if(CE == 2'b10) CE1 <= 1; + + if(CS) begin + if(WR) begin + mode[6] <= 1; + rd <= 0; + latch <= 0; + if(cmd) begin // command + if(|din[5:4]) begin + mode[5:0] <= din[5:0]; + newcmd <= 1; + state <= {1'b0, din[5] & ~din[4]}; + end else latch <= &mode[5:4]; + end else begin // data + state <= state[0] + ^mode[5:4] + 1; + if(state[0]) init[15:8] <= din; + else init[7:0] <= din; + end + end else begin + rd <= ~rd; + if(rd) latch <= 0; + end + end else if(state[1] && CE1 && !latch) begin + newcmd <= 0; + CE1 <= 0; + case(mode[3:1]) + 3'b000, 3'b001: + if(mode[6]) begin + mode[7:6] <= 2'b00; + count <= init; + end else begin + count <= count - 1; + if(c1) mode[7] <= 1; + end + 3'b010, 3'b110: begin + mode[7] <= ~c2; + if(c1 | newcmd) begin + mode[6] <= 1'b0; + count <= init; + end else count <= count - 1; + end + 3'b011, 3'b111: begin + if(c1 | c2 | newcmd) begin + mode[7:6] <= {~mode[7] | newcmd, 1'b0}; + count <= {init[15:1], (~mode[7] | newcmd) & init[0]}; + end else count <= count - 2; + end + 3'b100, 3'b101: + if(mode[6]) begin + mode[7:6] <= 2'b10; + count <= init; + strobe <= 1; + end else begin + count <= count - 1; + if(c1) begin + if(strobe) mode[7] <= 0; + strobe <= 0; + end else mode[7] <= 1; + end + endcase + end + end + +endmodule Index: HW/cache_controller.v =================================================================== --- HW/cache_controller.v (nonexistent) +++ HW/cache_controller.v (revision 2) @@ -0,0 +1,205 @@ +////////////////////////////////////////////////////////////////////////////////// +// +// This file is part of the Next186 Soc PC project +// http://opencores.org/project,next186 +// +// Filename: cache_controller.v +// Description: Part of the Next186 SoC PC project, cache controller +// Version 1.0 +// Creation date: Jan2012 +// +// Author: Nicolae Dumitrache +// e-mail: ndumitrache@opencores.org +// +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2012 Nicolae Dumitrache +// +// This source file may be used and distributed without +// restriction provided that this copyright statement is not +// removed from the file and that any derivative work contains +// the original copyright notice and the associated disclaimer. +// +// This source file is free software; you can redistribute it +// and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; +// either version 2.1 of the License, or (at your option) any +// later version. +// +// This source is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General +// Public License along with this source; if not, download it +// from http://www.opencores.org/lgpl.shtml +// +/////////////////////////////////////////////////////////////////////////////////// +// Additional Comments: +// +// preloaded with bootstrap code +////////////////////////////////////////////////////////////////////////////////// + +`timescale 1ns / 1ps +`define WAYS 2 // 2^ways +`define SETS 4 // 2^sets + +module cache_controller( + input [20:0] addr, + output [31:0] dout, + input [31:0]din, + input clk, + input mreq, + input [3:0]wmask, + output ce, // clock enable for CPU + input [15:0]ddr_din, + output reg[15:0]ddr_dout, + input ddr_clk, + input cache_write_data, // 1 when data must be written to cache, on posedge ddr_clk + input cache_read_data, // 1 when data must be read from cache, on posedge ddr_clk + output reg ddr_rd = 0, + output reg ddr_wr = 0, + output reg [12:0] waddr, + input flush + ); + + reg flushreq = 1'b0; + reg [`WAYS+`SETS:0]flushcount = 0; + wire r_flush = flushcount[`WAYS+`SETS]; + wire [`SETS-1:0]index = r_flush ? flushcount[`SETS-1:0] : addr[8+`SETS-1:8]; + wire [(1<<`WAYS)-1:0]fit; + wire [(1<<`WAYS)-1:0]free; + wire wr = |wmask; + + reg [(1<<`WAYS)-1:0]cache_dirty[0:(1<<`SETS)-1] = + {4'h0, 4'h0, 4'h0, 4'h0, 4'h0, 4'h0, 4'h0, 4'h0, 4'h0, 4'h0, 4'h0, 4'h0, 4'h1, 4'h1, 4'h1, 4'h1}; + reg [`WAYS-1:0]cache_lru[0:(1<<`WAYS)-1][0:(1<<`SETS)-1] = + {{2'h0, 2'h0, 2'h0, 2'h0, 2'h0, 2'h0, 2'h0, 2'h0, 2'h0, 2'h0, 2'h0, 2'h0, 2'h0, 2'h0, 2'h0, 2'h0}, + {2'h1, 2'h1, 2'h1, 2'h1, 2'h1, 2'h1, 2'h1, 2'h1, 2'h1, 2'h1, 2'h1, 2'h1, 2'h1, 2'h1, 2'h1, 2'h1}, + {2'h2, 2'h2, 2'h2, 2'h2, 2'h2, 2'h2, 2'h2, 2'h2, 2'h2, 2'h2, 2'h2, 2'h2, 2'h2, 2'h2, 2'h2, 2'h2}, + {2'h3, 2'h3, 2'h3, 2'h3, 2'h3, 2'h3, 2'h3, 2'h3, 2'h3, 2'h3, 2'h3, 2'h3, 2'h3, 2'h3, 2'h3, 2'h3}}; + reg [12-`SETS:0]cache_addr[0:(1<<`WAYS)-1][0:(1<<`SETS)-1]= + {{9'h000, 9'h000, 9'h000, 9'h000, 9'h000, 9'h000, 9'h000, 9'h000, 9'h000, 9'h000, 9'h000, 9'h000, 9'h0ff, 9'h0ff, 9'h0ff, 9'h0ff}, + {9'h001, 9'h001, 9'h001, 9'h001, 9'h001, 9'h001, 9'h001, 9'h001, 9'h001, 9'h001, 9'h001, 9'h001, 9'h000, 9'h000, 9'h000, 9'h000}, + {9'h002, 9'h002, 9'h002, 9'h002, 9'h002, 9'h002, 9'h002, 9'h002, 9'h002, 9'h002, 9'h002, 9'h002, 9'h001, 9'h001, 9'h001, 9'h001}, + {9'h003, 9'h003, 9'h003, 9'h003, 9'h003, 9'h003, 9'h003, 9'h003, 9'h003, 9'h003, 9'h003, 9'h003, 9'h002, 9'h002, 9'h002, 9'h002}}; + + reg [2:0]STATE = 0; + reg [6:0]lowaddr = 0; //cache mem address + reg s_lowaddr5 = 0; + wire [31:0]cache_QA; + wire [`WAYS-1:0]lru[(1<<`WAYS)-1:0]; + + genvar i; + for(i=0; i<(1<<`WAYS); i=i+1) begin + assign fit[i] = ~r_flush && (cache_addr[i][index] == addr[20:8+`SETS]); + assign free[i] = r_flush ? (flushcount[`WAYS+`SETS-1:`SETS] == i) : ~|cache_lru[i][index]; + assign lru[i] = {`WAYS{fit[i]}} & cache_lru[i][index]; + end + + wire hit = |fit; + wire st0 = STATE == 3'b000; + assign ce = st0 && (~mreq || hit); + wire dirty = |(free & cache_dirty[index]); + + wire [`WAYS-1:0]blk = flushcount[`WAYS+`SETS-1:`SETS] | {|fit[3:2], fit[3] | fit[1]}; + wire [`WAYS-1:0]fblk = {|free[3:2], free[3] | free[1]}; + wire [`WAYS-1:0]csblk = lru[0] | lru[1] | lru[2] | lru[3]; + + always @(posedge ddr_clk) begin + if(cache_write_data || cache_read_data) lowaddr <= lowaddr + 1; + ddr_dout <= lowaddr[0] ? cache_QA[15:0] : cache_QA[31:16]; + end + + cache cache_mem + ( + .clka(ddr_clk), // input clka + .ena(cache_write_data | cache_read_data), // input ena + .wea({4{cache_write_data}} & {lowaddr[0], lowaddr[0], ~lowaddr[0], ~lowaddr[0]}), // input [3 : 0] wea + .addra({blk, ~index[`SETS-1:2], index[1:0], lowaddr[6:1]}), // input [11 : 0] addra + .dina({ddr_din, ddr_din}), // input [31 : 0] dina + .douta(cache_QA), // output [31 : 0] douta + .clkb(clk), // input clkb + .enb(mreq & hit & st0), // input enb + .web({4{mreq & hit & st0 & wr}} & wmask), // input [3 : 0] web + .addrb({blk, ~index[`SETS-1:2], index[1:0], addr[7:2]}), // input [11 : 0] addrb + .dinb(din), // input [31 : 0] dinb + .doutb(dout) // output [31 : 0] doutb + ); + + + for(i=0; i<(1<<`WAYS); i=i+1) + always @(posedge clk) + if(st0 && mreq) + if(hit) begin + cache_lru[i][index] <= fit[i] ? {`WAYS{1'b1}} : cache_lru[i][index] - (cache_lru[i][index] > csblk); + if(fit[i]) cache_dirty[index][i] <= cache_dirty[index][i] | wr; + end else if(free[i]) cache_dirty[index][i] <= 1'b0; + + + always @(posedge clk) begin + s_lowaddr5 <= lowaddr[6]; + flushreq <= ~flushcount[`WAYS+`SETS] & (flushreq | flush); + + case(STATE) + 3'b000: begin + if(mreq && !hit) begin // cache miss + waddr <= {cache_addr[fblk][index], index}; + if(!r_flush) cache_addr[fblk][index] <= addr[20:8+`SETS]; + ddr_rd <= ~dirty & ~r_flush; + ddr_wr <= dirty; + STATE <= dirty ? 3'b011 : 3'b100; + end else flushcount[`WAYS+`SETS] <= flushcount[`WAYS+`SETS] | flushreq; + end + 3'b011: begin // write cache to ddr + ddr_rd <= ~r_flush; //1'b1; + if(s_lowaddr5) begin + ddr_wr <= 1'b0; + STATE <= 3'b111; + end + end + 3'b111: begin // read cache from ddr + if(~s_lowaddr5) STATE <= 3'b100; + end + 3'b100: begin + if(r_flush) begin + flushcount <= flushcount + 1; + STATE <= 3'b000; + end else if(s_lowaddr5) STATE <= 3'b101; + end + 3'b101: begin + ddr_rd <= 1'b0; + if(~s_lowaddr5) STATE <= 3'b000; + end + endcase + end + +endmodule + + +module seg_map( + input CLK, + input [3:0]cpuaddr, + output [8:0]cpurdata, + input [8:0]cpuwdata, + input [4:0]memaddr, + output [8:0]memdata, + input WE + ); + + reg [8:0]map[0:31] = {9'h000, 9'h001, 9'h002, 9'h003, 9'h004, 9'h005, 9'h006, 9'h007, 9'h008, 9'h009, + 9'h00a, 9'h00b, // VGA seg 1 and 2 + 9'h012, 9'h013, 9'h014, 9'h015, + 9'h016, // HMA + 9'h001, 9'h002, 9'h003, 9'h004, 9'h005, 9'h006, 9'h007, 9'h008, 9'h009, + 9'h00a, 9'h00b, 9'h00c, 9'h00d, 9'h00e, 9'h00f}; // VGA seg 1..6 + assign memdata = map[memaddr]; + assign cpurdata = map[{1'b0, cpuaddr}]; +// initial $readmemh("segmap.mem", map); + + always @(posedge CLK) + if(WE) map[{1'b0, cpuaddr}] <= cpuwdata; + +endmodule Index: HW/sdram.v =================================================================== --- HW/sdram.v (nonexistent) +++ HW/sdram.v (revision 2) @@ -0,0 +1,200 @@ +`timescale 1ns / 100ps +////////////////////////////////////////////////////////////////////////////////// +// +// This file is part of the Next186 Soc PC project +// http://opencores.org/project,next186 +// +// Filename: sdram.v +// Description: Part of the Next186 SoC PC project, SDRAM controller +// Version 1.0 +// Creation date: Feb2014 +// +// Author: Nicolae Dumitrache +// e-mail: ndumitrache@opencores.org +// +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2014 Nicolae Dumitrache +// +// This source file may be used and distributed without +// restriction provided that this copyright statement is not +// removed from the file and that any derivative work contains +// the original copyright notice and the associated disclaimer. +// +// This source file is free software; you can redistribute it +// and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; +// either version 2.1 of the License, or (at your option) any +// later version. +// +// This source is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General +// Public License along with this source; if not, download it +// from http://www.opencores.org/lgpl.shtml +// +/////////////////////////////////////////////////////////////////////////////////// +// Additional Comments: +////////////////////////////////////////////////////////////////////////////////// + +`define RD1 8'h10 // 32 bytes - cmd 10 +`define RD2 8'h80 // 256 bytes - cmd 11 +`define WR2 8'h80 // 256 bytes - cmd 01 +`define PitchBits 1 + +`define ColBits 8 // column bits +`define RowBits 12 // row bits +`define BankBits 2 // bank bits + +`define tRP 3 +`define tMRD 2 +`define tRCD 3 +`define tRC 9 +`define CL 3 // CAS latency +`define tREF 64 // ms + +`define RFB 11 // refresh bit = floor(log2(CLK*`tREF/(2^RowBits))) + + +module SDRAM_16bit( + input sys_CLK, // clock + input [1:0]sys_CMD, // 00=nop, 01 = write WR2 bytes, 10=read RD1 bytes, 11=read RD2 bytes + input [`RowBits+`BankBits+`ColBits-`PitchBits-1:0]sys_ADDR, // word address, multiple of 2^PitchBits words + input [15:0]sys_DIN, // data input + output reg [15:0]sys_DOUT, + output reg sys_rd_data_valid = 0, // data valid out + output reg sys_wr_data_valid = 0, // data valid in + output reg [1:0]sys_cmd_ack = 0, // command acknowledged + + output reg [3:0]sdr_n_CS_WE_RAS_CAS = 4'b1111, // SDRAM #CS, #WE, #RAS, #CAS + output reg [1:0]sdr_BA, // SDRAM bank address + output reg [12:0]sdr_ADDR, // SDRAM address + inout [15:0]sdr_DATA, // SDRAM data + output reg [1:0]sdr_DQM = 2'b11 // SDRAM DQM + ); + + reg [`RowBits-1:0]actLine[3:0]; + reg [(1<<`BankBits)-1:0]actBank = 0; + reg [2:0]STATE = 0; + reg [2:0]RET; // return state + reg [6:0]DLY; // delay + reg [15:0]counter = 0; // refresh counter + reg rfsh = 1; // refresh bit + reg [`ColBits-`PitchBits-1:0]colAddr; + reg [`BankBits-1:0]bAddr; + reg [`RowBits-1:0]linAddr; + reg [15:0]reg_din; + reg [2:0]out_data_valid = 0; + + assign sdr_DATA = out_data_valid[2] ? reg_din : 16'hzzzz; + + always @(posedge sys_CLK) begin + counter <= counter + 1; + sdr_n_CS_WE_RAS_CAS <= 4'b1xxx; // NOP + STATE <= 1; + reg_din <= sys_DIN; + out_data_valid <= {out_data_valid[1:0], sys_wr_data_valid}; + DLY <= DLY - 1; + sys_DOUT <= sdr_DATA; + + case(STATE) + 0: begin + sys_rd_data_valid <= 1'b0; + if(sdr_DQM[0]) STATE <= counter[15] ? 2 : 0; // initialization, wait >200uS + else begin // wait new command + if(rfsh != counter[`RFB]) begin + rfsh <= counter[`RFB]; + STATE <= 2; // precharge all + end else if(|sys_CMD) begin + sys_cmd_ack <= sys_CMD; + {linAddr, bAddr, colAddr} <= sys_ADDR; + STATE <= 5; + end else STATE <= 0; + end + end + + 1: begin + if(DLY == 2) sys_wr_data_valid <= 1'b0; + if(DLY == 0) STATE <= RET; // NOP for DLY clocks, return to RET state + end + + 2: begin // precharge all + sdr_n_CS_WE_RAS_CAS <= 4'b0001; + sdr_ADDR[10] <= 1'b1; + RET <= sdr_DQM[0] ? 3 : 4; + DLY <= `tRP - 2; + actBank <= 0; + end + + 3: begin // Mode Register Set + sdr_n_CS_WE_RAS_CAS <= 4'b0000; + sdr_ADDR <= 13'b00_0_0_00_000_0_111 + (`CL<<4); // burst read/burst write _ normal mode _ `CL CAS latency _ sequential _ full page burst + sdr_BA <= 2'b00; + RET <= 4; + DLY <= `tMRD - 2; + end + + 4: begin // autorefresh + sdr_n_CS_WE_RAS_CAS <= 4'b0100; + if(rfsh != counter[`RFB]) RET <= 4; + else begin + sdr_DQM <= 2'b00; + RET <= 0; + end + DLY <= `tRC - 2; + end + + 5: begin // read/write + sdr_BA <= bAddr; + if(actBank[bAddr]) // bank active + if(actLine[bAddr] == linAddr) begin // line already active + sdr_ADDR[10] <= 1'b0; // no auto precharge + sdr_ADDR[`ColBits-1:0] <= {colAddr, {`PitchBits{1'b0}}}; + RET <= 7; + if(sys_cmd_ack[1]) begin // read + sdr_n_CS_WE_RAS_CAS <= 4'b0110; // read command + DLY <= `CL - 1; + end else begin // write + DLY <= 1; + sys_wr_data_valid <= 1'b1; + end + end else begin // bank precharge + sdr_n_CS_WE_RAS_CAS <= 4'b0001; + sdr_ADDR[10] <= 1'b0; + actBank[bAddr] <= 1'b0; + RET <= 5; + DLY <= `tRP - 2; + end + else begin // bank activate + sdr_n_CS_WE_RAS_CAS <= 4'b0101; + sdr_ADDR[`RowBits-1:0] <= linAddr; + actBank[bAddr] <= 1'b1; + actLine[bAddr] <= linAddr; + RET <= 5; + DLY <= `tRCD - 2; + end + end + + 6: begin // end read/write phase + sys_cmd_ack <= 2'b00; + sdr_n_CS_WE_RAS_CAS <= 4'b0011; // burst stop + STATE <= sys_cmd_ack[1] ? 1 : 0; // read write + RET <= 0; + DLY <= 2; + end + + 7: begin // init read/write phase + if(sys_cmd_ack[1]) sys_rd_data_valid <= 1'b1; + else sdr_n_CS_WE_RAS_CAS <= 4'b0010; // write command + RET <= 6; + DLY <= sys_cmd_ack[1] ? sys_cmd_ack[0] ? `RD2 - 6 : `RD1 - 6 : `WR2 - 2; + end + + endcase + end + +endmodule Index: HW/ddr_186.v =================================================================== --- HW/ddr_186.v (nonexistent) +++ HW/ddr_186.v (revision 2) @@ -0,0 +1,770 @@ +////////////////////////////////////////////////////////////////////////////////// +// +// This file is part of the Next186 Soc PC project +// http://opencores.org/project,next186 +// +// Filename: ddr_186.v +// Description: Part of the Next186 SoC PC project, main system, RAM interface +// Version 2.0 +// Creation date: Apr2014 +// +// Author: Nicolae Dumitrache +// e-mail: ndumitrache@opencores.org +// +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2012 Nicolae Dumitrache +// +// This source file may be used and distributed without +// restriction provided that this copyright statement is not +// removed from the file and that any derivative work contains +// the original copyright notice and the associated disclaimer. +// +// This source file is free software; you can redistribute it +// and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; +// either version 2.1 of the License, or (at your option) any +// later version. +// +// This source is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General +// Public License along with this source; if not, download it +// from http://www.opencores.org/lgpl.shtml +// +/////////////////////////////////////////////////////////////////////////////////// +// Additional Comments: +// +// 25Apr2012 - added SD card SPI support +// 15May2012 - added PIT 8253 (sound + timer INT8) +// 24May2012 - added PIC 8259 +// 28May2012 - RS232 boot loader does not depend on CPU speed anymore (uses timer0) +// 01Feb2013 - ADD 8042 PS2 Keyboard & Mouse controller +// 27Feb2013 - ADD RTC +// 04Apr2013 - ADD NMI, port 3bc for 8 leds +// +// Feb2014 - ported for SDRAM, added USB host serial communication +// - added video modes 0dh, 12h +// - support for ModeX +////////////////////////////////////////////////////////////////////////////////// + +/* ----------------- implemented ports ------------------- +0001 - bit0=write RS232, bit1=write USB host out, bit2=USB host reset + - bit0=auto cache flush, on WORD write only + +0002 - 32 bit CPU data port R/W, lo first +0003 - 32 bit CPU command port W + 16'b00000cvvvvvvvvvv = set r/w pointer - 256 32bit integers, 1024 instructions. c=1 for code write, 0 for data read/write + 16'b100wwwvvvvvvvvvv = run ip - 1024 instructions, 3 bit data window offs + +0021, 00a1 - interrupt controller data ports. R/W interrupt mask, 1disabled/0enabled (bit0=timer, bit1=keyboard, bit3=RTC, bit4=mouse) + +0040-0043 - PIT 8253 ports + +0x60, 0x64 - 8042 keyboard/mouse data and cfg + +0061 - bits1:0 speaker on/off (write only) + +0070 - RTC (16bit write only counter value). RTC is incremented with 1Mhz and at set value sends INT70h, then restart from 0 + When set, it restarts from 0. If the set value is 0, it will send INT70h only once, if it was not already 0 + +080h-08fh - memory map: bit9:0=64 Kbytes DDRAM segment index (up to 1024 segs = 64MB), mapped over + PORT[3:0] 80186 addressable segment + +0200h-020fh - joystick port - returns 0ffh + +0378 - sound port: 8bit=Covox & DSS compatible, 16bit = stereo L+R - fifo sampled at 44100Hz + bit4 of port 03DA is 1 when the sound queue is full. If it is 0, the queue may accept up to 1152 stereo samples (L + R), so 2304 16bit writes. + +0379 - parallel port control: bit6 = 1 when DSS queue is full + +03C0 - VGA mode + index 10h: + bit0 = graphic(1)/text(0) + bit3 = text mode flash enabled(1) + bit4 = half mode (EGA) + bit6 = 320x200(1)/640x480(0) + index 13h: bit[3:0] = hrz pan + +03C4, 03C5 (Sequencer registers) - idx2[3:0] = write plane, idx4[3]=0 for planar (rw) + +03C6 - DAC mask (rw) +03C7 - DAC read index (rw) +03C8 - DAC write index (rw) +03C9 - DAC color (rw) +03CB - font: write WORD = set index (8 bit), r/w BYTE = r/w font data + +03CE, 03CF (Graphics registers) (rw) + 0: setres <= din[3:0]; + 1: enable_setres <= din[3:0]; + 2: color_compare <= din[3:0]; + 3: logop <= din[4:3]; + 4: rplane <= din[1:0]; + 5: rwmode <= {din[3], din[1:0]}; + 7: color_dont_care <= din[3:0]; + 8: bitmask <= din[7:0]; (1=CPU, 0=latch) + +03DA - read VGA status, bit0=1 on vblank or hblank, bit1=RS232in, bit2=USB host serial in, bit3=1 on vblank, bit4=sound queue full, bit5=DSP32 halt, bit7=1 always, bit15:8=SD SPI byte read + write bit7=SD SPI MOSI bit, SPI CLK 0->1 (BYTE write only), bit8 = SD card chip select (WORD write only) + also reset the 3C0 port index flag + +03B4, 03D4 - VGA CRT write index: + 06h: bit 7=1 for 200lines, 0 for 240 lines + 0Ah(bit 5 only): hide cursor + 0Ch: HI screen offset + 0Dh: LO screen offset + 0Eh: HI cursor pos + 0Fh: LO cursor pos + 13h: scan line offset +03B5, 03D5 - VGA CRT read/write data +*/ + + +`timescale 1ns / 1ps + +module system + ( + output sdr_CLK_out, + output [3:0]sdr_n_CS_WE_RAS_CAS, + output [1:0]sdr_BA, + output [12:0]sdr_ADDR, + inout [15:0]sdr_DATA, + output [1:0]sdr_DQM, + input CLK_32MHZ, + output reg [5:0]VGA_R, + output reg [5:0]VGA_G, + output reg [5:0]VGA_B, + output wire VGA_HSYNC, + output wire VGA_VSYNC, + input BTN_RESET, // Reset + input BTN_NMI, // NMI + output [7:0]LED, // HALT + input RS232_DCE_RXD, + output reg RS232_DCE_TXD, + input RS232_HOST_RXD, + output reg RS232_HOST_TXD, + output reg RS232_HOST_RST, + + output reg SD_n_CS = 1, + output wire SD_DI, + output reg SD_CK = 0, + input SD_DO, + + output reg AUD_L, + output reg AUD_R, + inout PS2_CLK1, + inout PS2_CLK2, + inout PS2_DATA1, + inout PS2_DATA2 + ); + + wire [15:0]cntrl0_user_input_data;//i + wire [1:0]sys_cmd_ack; + wire sys_rd_data_valid; + wire sys_wr_data_valid; + wire [15:0]sys_DOUT; // sdr data out + wire [12:0]waddr; + wire [31:0] DOUT; + wire [15:0]CPU_DOUT; + wire [15:0]PORT_ADDR; + wire [31:0] DRAM_dout; + wire [20:0] ADDR; + wire IORQ; + wire WR; + wire INTA; + wire WORD; + wire [3:0] RAM_WMASK; + wire Empty; // fifo empty + wire hblnk; + wire vblnk; + wire [9:0]hcount; + wire [9:0]vcount; + reg [3:0]vga_hrzpan = 0; + wire [3:0]vga_hrzpan_req; + wire [9:0]hcount_pan = hcount + vga_hrzpan - 17; + wire displ_on = !(hblnk | vblnk | Empty); + wire [17:0]DAC_COLOR; + wire Full; + wire AlmostFull; + wire AlmostEmpty; + wire clk_25; + wire clk_cpu; + wire clk_sdr; + wire CPU_CE; // CPU clock enable + wire CE; + wire CE_186; + wire ddr_rd; + wire ddr_wr; + wire TIMER_OE = PORT_ADDR[15:2] == 14'b00000000010000; // 40h..43h + wire VGA_DAC_OE = PORT_ADDR[15:4] == 12'h03c && PORT_ADDR[3:0] <= 4'h9; // 3c0h..3c9h + wire LED_PORT = PORT_ADDR[15:0] == 16'h03bc; + wire SPEAKER_PORT = PORT_ADDR[15:0] == 16'h0061; + wire MEMORY_MAP = PORT_ADDR[15:4] == 12'h008; + wire VGA_FONT_OE = PORT_ADDR[15:0] == 16'h03cb; + wire RS232_OE = PORT_ADDR[15:0] == 16'h0001; + wire INPUT_STATUS_OE = PORT_ADDR[15:0] == 16'h03da; + wire VGA_CRT_OE = (PORT_ADDR[15:1] == 15'b000000111011010) || (PORT_ADDR[15:1] == 15'b000000111101010); // 3b4h, 3b5h, 3d4h, 3d5h + wire RTC_SELECT = PORT_ADDR[15:0] == 16'h0070; + wire VGA_SC = PORT_ADDR[15:1] == (16'h03c4 >> 1); // 3c4h, 3c5h + wire VGA_GC = PORT_ADDR[15:1] == (16'h03ce >> 1); // 3ceh, 3cfh + wire PIC_OE = PORT_ADDR[15:8] == 8'h00 && PORT_ADDR[6:0] == 7'b0100001; // 21h, a1h + wire KB_OE = PORT_ADDR[15:4] == 12'h006 && {PORT_ADDR[3], PORT_ADDR[1:0]} == 3'b000; // 60h, 64h + wire JOYSTICK = PORT_ADDR[15:4] == 12'h020; // 0x200-0x20f + wire PARALLEL_PORT = PORT_ADDR[15:0] == 16'h0378; + wire PARALLEL_PORT_CTL = PORT_ADDR[15:0] == 16'h0379; + wire CPU32_PORT = PORT_ADDR[15:1] == (16'h0002 >> 1); // port 1 for data and 3 for instructions + wire [7:0]VGA_DAC_DATA; + wire [7:0]VGA_CRT_DATA; + wire [7:0]VGA_SC_DATA; + wire [7:0]VGA_GC_DATA; + wire [15:0]PORT_IN; + wire [7:0]TIMER_DOUT; + wire [7:0]KB_DOUT; + wire [7:0]PIC_DOUT; + wire HALT; + wire CLK44100x256; + wire sq_full; // sound queue full + wire dss_full; + wire AUDIO_L; + wire AUDIO_R; + wire [15:0]cpu32_data; + wire cpu32_halt; + + reg [1:0]cntrl0_user_command_register = 0; + reg [16:0]vga_ddr_row_col = 0; // video buffer offset (multiple of 4) + reg s_prog_full; + reg s_prog_empty; + reg [1:0]s_ddr_rd = 0; + reg [1:0]s_ddr_wr = 0; + reg crw = 0; // 1=cache read window + reg s_RS232_DCE_RXD; + reg s_RS232_HOST_RXD; + reg [4:0]rstcount = 0; + reg [18:0]s_displ_on = 0; // clk_25 delayed displ_on + reg [2:0]vga400 = 0; // 1 for 400 lines, 0 for 480 lines + reg [2:0]vgatext = 0; // 1 for text mode + reg [2:0]v240 = 0; + reg [2:0]planar = 0; + reg [2:0]half = 0; + wire vgaflash; + reg flashbit = 0; + reg [5:0]flashcount = 0; + wire [11:0]charcount = {vcount[8:4], 4'b0000} + {vcount[8:4], 6'b000000} + hcount_pan[9:3]; + wire [31:0]fifo_dout32; + wire [15:0]fifo_dout = (vgatext[1] ? hcount_pan[3] : vga400[1] ? hcount_pan[2] : hcount_pan[1]) ? fifo_dout32[31:16] : fifo_dout32[15:0]; + + reg [8:0]vga_ddr_row_count = 0; + reg [2:0]max_read; + reg [4:0]col_counter; + wire vga_end_frame = vga_ddr_row_count == (v240[0] ? 479 : 399); + reg [3:0]vga_repln_count = 0; // repeat line counter + wire [3:0]vga_repln = vgatext[0] ? 15 : (vga400[0] | half[0]) ? 1 : 0; + reg [7:0]vga_lnbytecount = 0; // line byte count (multiple of 4) + wire [4:0]vga_lnend = (vgatext[0] | half[0]) ? 5 : (vga400[0] | planar[0]) ? 10 : 20; // multiple of 32 (SDRAM resolution = 32) + reg [11:0]vga_font_counter = 0; + reg [7:0]vga_attr; + reg [4:0]RTCDIV25 = 0; + reg [1:0]RTCSYNC = 0; + reg [15:0]RTC = 0; + reg [15:0]RTCSET = 0; + wire RTCEND = RTC == RTCSET; + wire RTCDIVEND = RTCDIV25 == 24; + reg [12:0]cache_hi_addr; + wire [8:0]memmap; + wire [8:0]memmap_mux; + wire [7:0]font_dout; + wire [7:0]VGA_FONT_DATA; + wire vgatextreq; + wire vga400req; + wire planarreq; + wire v240req; + wire halfreq; + wire oncursor; + wire [11:0]cursorpos; + wire [15:0]scraddr; + reg flash_on; + reg speaker_on = 0; + reg [9:0]rNMI = 0; + wire [2:0]shift = half[1] ? ~hcount_pan[3:1] : ~hcount_pan[2:0]; + wire [2:0]pxindex = -hcount_pan[2:0]; + wire [3:0]VGA_MUX = vgatext[1] ? (font_dout[pxindex] ^ flash_on) ? vga_attr[3:0] : {vga_attr[7] & ~vgaflash, vga_attr[6:4]} : + {fifo_dout32[{2'b11, shift}], fifo_dout32[{2'b10, shift}], fifo_dout32[{2'b01, shift}], fifo_dout32[{2'b00, shift}]}; + reg s_vga_endline; + reg s_vga_endscanline = 0; + reg s_vga_endframe; + reg [20:0]sdraddr; + wire [3:0]vga_wplane; + wire [1:0]vga_rplane; + wire [7:0]vga_bitmask; // write 1=CPU, 0=VGA latch + wire [2:0]vga_rwmode; + wire [3:0]vga_setres; + wire [3:0]vga_enable_setres; + wire [1:0]vga_logop; + wire [3:0]vga_color_compare; + wire [3:0]vga_color_dont_care; + wire [7:0]vga_offset; + reg [2:0]auto_flush = 3'b000; +// wire slowport = !(INPUT_STATUS_OE || CPU32_PORT); +// wire WAITIO_ADDR = IORQ && !WR && CE_186 && slowport; +// reg rWAITIO_ADDR = 1'b0; +// wire WAITIO = WAITIO_ADDR && !rWAITIO_ADDR; +// reg [7:0]slowportdata; + + assign LED = {1'b0, !cpu32_halt, AUDIO_L, AUDIO_R, planarreq, |sys_cmd_ack, ~SD_n_CS, HALT}; + +// SD interface + reg [7:0]SDI; + assign SD_DI = CPU_DOUT[7]; + + assign PORT_IN[15:8] = + ({8{MEMORY_MAP}} & {7'b0000000, memmap[8]}) | + ({8{INPUT_STATUS_OE}} & SDI) | + ({8{CPU32_PORT}} & cpu32_data[15:8]); + + assign PORT_IN[7:0] = //INPUT_STATUS_OE ? {2'b1x, cpu32_halt, sq_full, vblnk, s_RS232_HOST_RXD, s_RS232_DCE_RXD, hblnk | vblnk} : CPU32_PORT ? cpu32_data[7:0] : slowportdata; + ({8{VGA_DAC_OE}} & VGA_DAC_DATA) | + ({8{VGA_FONT_OE}}& VGA_FONT_DATA) | + ({8{KB_OE}} & KB_DOUT) | + ({8{INPUT_STATUS_OE}} & {2'b1x, cpu32_halt, sq_full, vblnk, s_RS232_HOST_RXD, s_RS232_DCE_RXD, hblnk | vblnk}) | + ({8{VGA_CRT_OE}} & VGA_CRT_DATA) | + ({8{MEMORY_MAP}} & {memmap[7:0]}) | + ({8{TIMER_OE}} & TIMER_DOUT) | + ({8{PIC_OE}} & PIC_DOUT) | + ({8{VGA_SC}} & VGA_SC_DATA) | + ({8{VGA_GC}} & VGA_GC_DATA) | + ({8{JOYSTICK}})| + ({8{PARALLEL_PORT_CTL}} & {1'bx, dss_full, 6'bxxxxxx}) | + ({8{CPU32_PORT}} & cpu32_data[7:0]); + + dcm dcm_system + ( + .CLK_IN1(CLK_32MHZ), + .CLK_OUT1(clk_25), + .CLK_OUT2(clk_sdr), + .CLK_OUT3(sdr_CLK_out), + .CLK_OUT4(clk_cpu), + .CLK_OUT5(CLK44100x256) + ); + + + SDRAM_16bit SDR + ( + .sys_CLK(clk_sdr), // clock + .sys_CMD(cntrl0_user_command_register), // 00=nop, 01 = write 256 bytes, 10=read 32 bytes, 11=read 256 bytes + .sys_ADDR(sdraddr), // word address + .sys_DIN(cntrl0_user_input_data), // data input + .sys_DOUT(sys_DOUT), // data output + .sys_rd_data_valid(sys_rd_data_valid), // data valid read + .sys_wr_data_valid(sys_wr_data_valid), // data valid write + .sys_cmd_ack(sys_cmd_ack), // command acknowledged + + .sdr_n_CS_WE_RAS_CAS(sdr_n_CS_WE_RAS_CAS), // SDRAM #CS, #WE, #RAS, #CAS + .sdr_BA(sdr_BA), // SDRAM bank address + .sdr_ADDR(sdr_ADDR), // SDRAM address + .sdr_DATA(sdr_DATA), // SDRAM data + .sdr_DQM(sdr_DQM) // SDRAM DQM + ); + + fifo vga_fifo + ( + .wr_clk(clk_sdr), // input wr_clk + .rd_clk(clk_25), // input rd_clk + .din(sys_DOUT), // input [15 : 0] din + .wr_en(!crw && sys_rd_data_valid && !col_counter[4]), // input wr_en + .rd_en(s_displ_on[~vga_hrzpan] && ((vgatext[1] | half[1]) ? &hcount_pan[3:0] : (vga400[1] | planar[1]) ? &hcount_pan[2:0] : &hcount_pan[1:0])), // input rd_en + .dout({fifo_dout32[15:0], fifo_dout32[31:16]}), // output [31 : 0] dout + .full(Full), // output full + .empty(Empty), // output empty + .prog_full(AlmostFull), // output prog_full + .prog_empty(AlmostEmpty) // output prog_empty + ); + + VGA_SG VGA + ( + .tc_hsblnk(10'd639), + .tc_hssync(10'd655 + 10'd17), // +17 for hrz panning + .tc_hesync(10'd751 + 10'd17), // +17 for hrz panning + .tc_heblnk(10'd799), + .hcount(hcount), + .hsync(VGA_HSYNC), + .hblnk(hblnk), + .tc_vsblnk(v240[2] ? 10'd479 : 10'd399), + .tc_vssync(v240[2] ? 10'd489 : 10'd411), + .tc_vesync(v240[2] ? 10'd491 : 10'd413), + .tc_veblnk(v240[2] ? 10'd520 : 10'd446), + .vcount(vcount), + .vsync(VGA_VSYNC), + .vblnk(vblnk), + .clk(clk_25), + .ce(!Empty) + ); + + VGA_DAC dac + ( + .CE(VGA_DAC_OE && IORQ && CPU_CE), + .WR(WR), + .addr(PORT_ADDR[3:0]), + .din(CPU_DOUT[7:0]), + .dout(VGA_DAC_DATA), + .CLK(clk_cpu), + .VGA_CLK(clk_25), + .vga_addr((vgatext[1] | (~vga400[1] & planar[1])) ? {4'b0000, VGA_MUX} : (vga400[1] ? hcount_pan[1] : hcount_pan[0]) ? fifo_dout[15:8] : fifo_dout[7:0]), + .color(DAC_COLOR), + .vgatext(vgatextreq), + .vga400(vga400req), + .half(halfreq), + .vgaflash(vgaflash), + .setindex(INPUT_STATUS_OE && IORQ && CPU_CE), + .hrzpan(vga_hrzpan_req) + ); + + VGA_CRT crt + ( + .CE(IORQ && CPU_CE && VGA_CRT_OE), + .WR(WR), + .WORD(WORD), + .din(CPU_DOUT), + .addr(PORT_ADDR[0]), + .dout(VGA_CRT_DATA), + .CLK(clk_cpu), + .oncursor(oncursor), + .cursorpos(cursorpos), + .scraddr(scraddr), + .v240(v240req), + .offset(vga_offset) + ); + + VGA_SC sc + ( + .CE(IORQ && CPU_CE && VGA_SC), // 3c4, 3c5 + .WR(WR), + .WORD(WORD), + .din(CPU_DOUT), + .dout(VGA_SC_DATA), + .addr(PORT_ADDR[0]), + .CLK(clk_cpu), + .planarreq(planarreq), + .wplane(vga_wplane) + ); + + VGA_GC gc + ( + .CE(IORQ && CPU_CE && VGA_GC), + .WR(WR), + .WORD(WORD), + .din(CPU_DOUT), + .addr(PORT_ADDR[0]), + .CLK(clk_cpu), + .rplane(vga_rplane), + .bitmask(vga_bitmask), + .rwmode(vga_rwmode), + .setres(vga_setres), + .enable_setres(vga_enable_setres), + .logop(vga_logop), + .color_compare(vga_color_compare), + .color_dont_care(vga_color_dont_care), + .dout(VGA_GC_DATA) + ); + + sr_font VGA_FONT + ( + .clka(clk_25), // input clka + .wea(1'b0), // input [0 : 0] wea + .addra({fifo_dout[7:0], vcount[3:0]}), // input [11 : 0] addra + .dina(8'h00), // input [7 : 0] dina + .douta(font_dout), // output [7 : 0] douta + .clkb(clk_cpu), // input clkb + .web(WR & IORQ & VGA_FONT_OE & ~WORD & CPU_CE), // input [0 : 0] web + .addrb(vga_font_counter), // input [11 : 0] addrb + .dinb(CPU_DOUT[7:0]), // input [7 : 0] dinb + .doutb(VGA_FONT_DATA) // output [7 : 0] doutb + ); + + cache_controller cache_ctl + ( + .addr(ADDR), + .dout(DRAM_dout), + .din(DOUT), + .clk(clk_cpu), + .mreq(MREQ), + .wmask(RAM_WMASK), + .ce(CE), + .ddr_din(sys_DOUT), + .ddr_dout(cntrl0_user_input_data), + .ddr_clk(clk_sdr), + .ddr_rd(ddr_rd), + .ddr_wr(ddr_wr), + .waddr(waddr), + .cache_write_data(crw && sys_rd_data_valid), // read DDR, write to cache + .cache_read_data(crw && sys_wr_data_valid), + .flush(auto_flush == 3'b101) + ); + + wire I_KB; + wire I_MOUSE; + wire KB_RST; + KB_Mouse_8042 KB_Mouse + ( + .CS(IORQ && CPU_CE && KB_OE), // 60h, 64h + .WR(WR), + .cmd(PORT_ADDR[2]), // 64h + .din(CPU_DOUT[7:0]), + .dout(KB_DOUT), + .clk(clk_cpu), + .I_KB(I_KB), + .I_MOUSE(I_MOUSE), + .CPU_RST(KB_RST), + .PS2_CLK1(PS2_CLK1), + .PS2_CLK2(PS2_CLK2), + .PS2_DATA1(PS2_DATA1), + .PS2_DATA2(PS2_DATA2) + ); + + wire [7:0]PIC_IVECT; + wire INT; + wire timer_int; + PIC_8259 PIC + ( + .CS(PIC_OE && IORQ && CPU_CE), // 21h, a1h + .WR(WR), + .din(CPU_DOUT[7:0]), + .dout(PIC_DOUT), + .ivect(PIC_IVECT), + .clk(clk_cpu), + .INT(INT), + .IACK(INTA & CPU_CE), + .I({I_MOUSE, RTCEND, I_KB, timer_int}) + ); + + unit186 CPUUnit + ( + .INPORT(INTA ? {8'h00, PIC_IVECT} : PORT_IN), + .DIN(DRAM_dout), + .CPU_DOUT(CPU_DOUT), + .PORT_ADDR(PORT_ADDR), + .DOUT(DOUT), + .ADDR(ADDR), + .WMASK(RAM_WMASK), + .CLK(clk_cpu), + .CE(CE/* & !WAITIO*/), + .CPU_CE(CPU_CE), + .CE_186(CE_186), + .INTR(INT), + .NMI(rNMI[9]), + .RST(BTN_RESET || !rstcount[4]), + .INTA(INTA), + .LOCK(LOCK), + .HALT(HALT), + .MREQ(MREQ), + .IORQ(IORQ), + .WR(WR), + .WORD(WORD), + + .PLANAR(planarreq), + .VGA_WPLANE(vga_wplane), + .VGA_RPLANE(vga_rplane), + .VGA_BITMASK(vga_bitmask), + .VGA_RWMODE(vga_rwmode), + .VGA_SETRES(vga_setres), + .VGA_ENABLE_SETRES(vga_enable_setres), + .VGA_LOGOP(vga_logop), + .VGA_COLOR_COMPARE(vga_color_compare), + .VGA_COLOR_DONT_CARE(vga_color_dont_care) + ); + + seg_map seg_mapper + ( + .CLK(clk_cpu), + .cpuaddr(PORT_ADDR[3:0]), + .cpurdata(memmap), + .cpuwdata(CPU_DOUT[8:0]), + .memaddr(cache_hi_addr[12:8]), + .memdata(memmap_mux), + .WE(MEMORY_MAP & WR & WORD & IORQ & CPU_CE) + ); + + wire timer_spk; + timer_8253 timer + ( + .CS(TIMER_OE && IORQ && CPU_CE), + .WR(WR), + .addr(PORT_ADDR[1:0]), + .din(CPU_DOUT[7:0]), + .dout(TIMER_DOUT), + .CLK_25(clk_25), + .clk(clk_cpu), + .out0(timer_int), + .out2(timer_spk) + ); + + soundwave sound_gen + ( + .CLK(clk_cpu), + .CLK44100x256(CLK44100x256), + .data(CPU_DOUT), + .we(IORQ & CPU_CE & WR & PARALLEL_PORT), + .word(WORD), + .full(sq_full), // when not full, write max 2x1152 16bit samples + .dss_full(dss_full), + .AUDIO_L(AUDIO_L), + .AUDIO_R(AUDIO_R) + ); + + DSP32 DSP32_inst + ( + .clk(clk_cpu), + .cmd(PORT_ADDR[0]), // port 2=data, port 3=cmd (word only) + .ce(IORQ & CPU_CE & CPU32_PORT & WORD), + .wr(WR), + .din(CPU_DOUT), + .dout(cpu32_data), + .halt(cpu32_halt) + ); + + reg nop; + always @ (posedge clk_sdr) begin + s_prog_full <= AlmostFull; + s_prog_empty <= AlmostEmpty; + s_ddr_rd <= {s_ddr_rd[0], ddr_rd}; + s_ddr_wr <= {s_ddr_wr[0], ddr_wr}; + s_vga_endline <= vga_repln_count == vga_repln; + s_vga_endframe <= vga_end_frame; + cache_hi_addr <= s_ddr_wr[0] ? waddr : ADDR[20:8]; + nop <= sys_cmd_ack == 2'b00; + sdraddr <= s_prog_empty || !(s_ddr_wr[1] || s_ddr_rd[1]) ? {4'b0001, vga_ddr_row_col + vga_lnbytecount} : {memmap_mux[6:0], cache_hi_addr[7:0], 6'b000000}; + max_read <= &sdraddr[6:3] ? ~sdraddr[2:0] : 3'b111; // SDRAM row size = 256 words + + if(s_prog_empty) cntrl0_user_command_register <= 2'b10; // read 32 bytes VGA + else if(s_ddr_wr[1]) cntrl0_user_command_register <= 2'b01; // write 256 bytes cache + else if(s_ddr_rd[1]) cntrl0_user_command_register <= 2'b11; // read 256 bytes cache + else if(~s_prog_full) cntrl0_user_command_register <= 2'b10; // read 32 bytes VGA + else cntrl0_user_command_register <= 2'b00; + + if(!crw && sys_rd_data_valid) col_counter <= col_counter - 1; + if(nop) case(sys_cmd_ack) + 2'b10: begin + crw <= 1'b0; // VGA read + col_counter <= {1'b0, max_read, 1'b1}; + vga_lnbytecount <= vga_lnbytecount + max_read + 1; + end + 2'b01, 2'b11: crw <= 1'b1; // cache read/write + endcase + + if(s_vga_endscanline) begin + col_counter[3:1] <= col_counter[3:1] - vga_lnbytecount[2:0]; + vga_lnbytecount <= 0; + s_vga_endscanline <= 1'b0; + + if(s_vga_endframe) vga_ddr_row_col <= {{1'b0, scraddr[15:13]} + (vgatext[0] ? 4'b0111 : 4'b0100), scraddr[12:0]}; + else if(s_vga_endline) vga_ddr_row_col <= vga_ddr_row_col + (vgatext[0] ? 40 : {vga_offset, 1'b0}); + + if(s_vga_endline) vga_repln_count <= 0; + else vga_repln_count <= vga_repln_count + 1; + if(s_vga_endframe) begin + vga400[0] <= vga400req; + vgatext[0] <= vgatextreq; + v240[0] <= v240req; + planar[0] <= planarreq; + half[0] <= halfreq; + vga_ddr_row_count <= 0; + end else vga_ddr_row_count <= vga_ddr_row_count + 1; + end else s_vga_endscanline <= (vga_lnbytecount[7:3] == vga_lnend); + end + + always @ (posedge clk_cpu) begin + s_RS232_DCE_RXD <= RS232_DCE_RXD; + s_RS232_HOST_RXD <= RS232_HOST_RXD; + if(IORQ & CPU_CE) begin + if(WR & RS232_OE) begin + {RS232_HOST_RST, RS232_HOST_TXD, RS232_DCE_TXD} <= CPU_DOUT[2:0]; + if(WORD) auto_flush[2] <= CPU_DOUT[0]; + end + if(VGA_FONT_OE) vga_font_counter <= WR && WORD ? {CPU_DOUT[7:0], 4'b0000} : vga_font_counter + 1; + if(WR & SPEAKER_PORT) speaker_on <= &CPU_DOUT[1:0]; +// if(WR & LED_PORT) LED <= CPU_DOUT[7:0]; + end +// SD + if(CPU_CE) begin + SD_CK <= IORQ & INPUT_STATUS_OE & WR & ~WORD; + if(IORQ & INPUT_STATUS_OE & WR) begin + if(WORD) SD_n_CS <= ~CPU_DOUT[8]; // SD chip select + else SDI <= {SDI[6:0], SD_DO}; + end + end + + if(KB_RST) rstcount <= 0; + else if(CPU_CE && ~rstcount[4]) rstcount <= rstcount + 1; + +// RTC + RTCSYNC <= {RTCSYNC[0], RTCDIVEND}; + if(IORQ && CPU_CE && WR && WORD && RTC_SELECT) begin + RTC <= 0; + RTCSET <= CPU_DOUT; + end else if(RTCSYNC == 2'b01) begin + if(RTCEND) RTC <= 0; + else RTC <= RTC + 1; + end + + auto_flush[1:0] <= {auto_flush[0], vblnk}; + +/* rWAITIO_ADDR <= WAITIO_ADDR; + + slowportdata <= ({8{VGA_DAC_OE}} & VGA_DAC_DATA) | + ({8{VGA_FONT_OE}}& VGA_FONT_DATA) | + ({8{KB_OE}} & KB_DOUT) | + ({8{VGA_CRT_OE}} & VGA_CRT_DATA) | + ({8{MEMORY_MAP}} & {memmap[7:0]}) | + ({8{TIMER_OE}} & TIMER_DOUT) | + ({8{PIC_OE}} & PIC_DOUT) | + ({8{VGA_SC}} & VGA_SC_DATA) | + ({8{VGA_GC}} & VGA_GC_DATA) | + ({8{JOYSTICK}})| + ({8{PARALLEL_PORT_CTL}} & {1'bx, dss_full, 6'bxxxxxx}); +*/ + end + + always @ (posedge clk_25) begin + s_displ_on <= {s_displ_on[17:0], displ_on}; + vga_attr <= fifo_dout[15:8]; + flash_on <= (vgaflash & fifo_dout[15] & flashcount[5]) | (~oncursor && flashcount[4] && (charcount == cursorpos) && ((vcount[3:0] == 13) || vcount[3:0] == 14)); + + if(!vblnk) begin + flashbit <= 1; + vga400[2] <= vga400[1]; + vgatext[2] <= vgatext[1]; + v240[2] <= v240[1]; + planar[2] <= planar[1]; + half[2] <= half[1]; + end else if(flashbit) begin + flashcount <= flashcount + 1; + flashbit <= 0; + vga400[1] <= vga400[0]; + vgatext[1] <= vgatext[0]; + v240[1] <= v240[0]; + planar[1] <= planar[0]; + half[1] <= half[0]; + end + + if(RTCDIVEND) RTCDIV25 <= 0; // real time clock + else RTCDIV25 <= RTCDIV25 + 1; + + if(!BTN_NMI) rNMI <= 0; // NMI + else if(!rNMI[9] && RTCDIVEND) rNMI <= rNMI + 1; // 1Mhz increment + + {VGA_B, VGA_G, VGA_R} <= DAC_COLOR & {18{s_displ_on[17+vgatext[1]]}}; + if(VGA_VSYNC) vga_hrzpan <= half[0] ? {vga_hrzpan_req[2:0], 1'b0} : {1'b0, vga_hrzpan_req[2:0]}; + end + + reg [4:0]mix; + always @(posedge CLK44100x256) begin + mix <= mix + 1'b1; + AUD_L <= &mix & speaker_on ? timer_spk : AUDIO_L; + AUD_R <= &mix & speaker_on ? timer_spk : AUDIO_R; + end + +endmodule + Index: HW/font.coe =================================================================== --- HW/font.coe (nonexistent) +++ HW/font.coe (revision 2) @@ -0,0 +1,131 @@ +memory_initialization_radix = 16; +memory_initialization_vector = + +00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,7E,81,A5,81,81,A5,99,81,81,7E,00,00,00,00, +00,00,7E,FF,DB,FF,FF,DB,E7,FF,FF,7E,00,00,00,00,00,00,00,00,6C,FE,FE,FE,FE,7C,38,10,00,00,00,00, +00,00,00,00,10,38,7C,FE,7C,38,10,00,00,00,00,00,00,00,00,18,3C,3C,E7,E7,E7,18,18,3C,00,00,00,00, +00,00,00,18,3C,7E,FF,FF,7E,18,18,3C,00,00,00,00,00,00,00,00,00,00,18,3C,3C,18,00,00,00,00,00,00, +FF,FF,FF,FF,FF,FF,E7,C3,C3,E7,FF,FF,FF,FF,FF,FF,00,00,00,00,00,3C,66,42,42,66,3C,00,00,00,00,00, +FF,FF,FF,FF,FF,C3,99,BD,BD,99,C3,FF,FF,FF,FF,FF,00,00,1E,06,0E,1A,78,CC,CC,CC,CC,78,00,00,00,00, +00,00,3C,66,66,66,66,3C,18,7E,18,18,00,00,00,00,00,00,3F,33,3F,30,30,30,30,70,F0,E0,00,00,00,00, +00,00,7F,63,7F,63,63,63,63,67,E7,E6,C0,00,00,00,00,00,00,18,18,DB,3C,E7,3C,DB,18,18,00,00,00,00, +00,80,C0,E0,F0,F8,FE,F8,F0,E0,C0,80,00,00,00,00,00,02,06,0E,1E,3E,FE,3E,1E,0E,06,02,00,00,00,00, +00,00,18,3C,7E,18,18,18,7E,3C,18,00,00,00,00,00,00,00,66,66,66,66,66,66,66,00,66,66,00,00,00,00, +00,00,7F,DB,DB,DB,7B,1B,1B,1B,1B,1B,00,00,00,00,00,7C,C6,60,38,6C,C6,C6,6C,38,0C,C6,7C,00,00,00, +00,00,00,00,00,00,00,00,FE,FE,FE,FE,00,00,00,00,00,00,18,3C,7E,18,18,18,7E,3C,18,7E,00,00,00,00, +00,00,18,3C,7E,18,18,18,18,18,18,18,00,00,00,00,00,00,18,18,18,18,18,18,18,7E,3C,18,00,00,00,00, +00,00,00,00,00,18,0C,FE,0C,18,00,00,00,00,00,00,00,00,00,00,00,30,60,FE,60,30,00,00,00,00,00,00, +00,00,00,00,00,00,C0,C0,C0,FE,00,00,00,00,00,00,00,00,00,00,00,28,6C,FE,6C,28,00,00,00,00,00,00, +00,00,00,00,10,38,38,7C,7C,FE,FE,00,00,00,00,00,00,00,00,00,FE,FE,7C,7C,38,38,10,00,00,00,00,00, +00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,18,3C,3C,3C,18,18,18,00,18,18,00,00,00,00, +00,66,66,66,24,00,00,00,00,00,00,00,00,00,00,00,00,00,00,6C,6C,FE,6C,6C,6C,FE,6C,6C,00,00,00,00, +18,18,7C,C6,C2,C0,7C,06,06,86,C6,7C,18,18,00,00,00,00,00,00,C2,C6,0C,18,30,60,C6,86,00,00,00,00, +00,00,38,6C,6C,38,76,DC,CC,CC,CC,76,00,00,00,00,00,30,30,30,60,00,00,00,00,00,00,00,00,00,00,00, +00,00,0C,18,30,30,30,30,30,30,18,0C,00,00,00,00,00,00,30,18,0C,0C,0C,0C,0C,0C,18,30,00,00,00,00, +00,00,00,00,00,66,3C,FF,3C,66,00,00,00,00,00,00,00,00,00,00,00,18,18,7E,18,18,00,00,00,00,00,00, +00,00,00,00,00,00,00,00,00,18,18,18,30,00,00,00,00,00,00,00,00,00,00,FE,00,00,00,00,00,00,00,00, +00,00,00,00,00,00,00,00,00,00,18,18,00,00,00,00,00,00,00,00,02,06,0C,18,30,60,C0,80,00,00,00,00, +00,00,38,6C,C6,C6,D6,D6,C6,C6,6C,38,00,00,00,00,00,00,18,38,78,18,18,18,18,18,18,7E,00,00,00,00, +00,00,7C,C6,06,0C,18,30,60,C0,C6,FE,00,00,00,00,00,00,7C,C6,06,06,3C,06,06,06,C6,7C,00,00,00,00, +00,00,0C,1C,3C,6C,CC,FE,0C,0C,0C,1E,00,00,00,00,00,00,FE,C0,C0,C0,FC,06,06,06,C6,7C,00,00,00,00, +00,00,38,60,C0,C0,FC,C6,C6,C6,C6,7C,00,00,00,00,00,00,FE,C6,06,06,0C,18,30,30,30,30,00,00,00,00, +00,00,7C,C6,C6,C6,7C,C6,C6,C6,C6,7C,00,00,00,00,00,00,7C,C6,C6,C6,7E,06,06,06,0C,78,00,00,00,00, +00,00,00,00,18,18,00,00,00,18,18,00,00,00,00,00,00,00,00,00,18,18,00,00,00,18,18,30,00,00,00,00, +00,00,00,06,0C,18,30,60,30,18,0C,06,00,00,00,00,00,00,00,00,00,7E,00,00,7E,00,00,00,00,00,00,00, +00,00,00,60,30,18,0C,06,0C,18,30,60,00,00,00,00,00,00,7C,C6,C6,0C,18,18,18,00,18,18,00,00,00,00, +00,00,00,7C,C6,C6,DE,DE,DE,DC,C0,7C,00,00,00,00,00,00,10,38,6C,C6,C6,FE,C6,C6,C6,C6,00,00,00,00, +00,00,FC,66,66,66,7C,66,66,66,66,FC,00,00,00,00,00,00,3C,66,C2,C0,C0,C0,C0,C2,66,3C,00,00,00,00, +00,00,F8,6C,66,66,66,66,66,66,6C,F8,00,00,00,00,00,00,FE,66,62,68,78,68,60,62,66,FE,00,00,00,00, +00,00,FE,66,62,68,78,68,60,60,60,F0,00,00,00,00,00,00,3C,66,C2,C0,C0,DE,C6,C6,66,3A,00,00,00,00, +00,00,C6,C6,C6,C6,FE,C6,C6,C6,C6,C6,00,00,00,00,00,00,3C,18,18,18,18,18,18,18,18,3C,00,00,00,00, +00,00,1E,0C,0C,0C,0C,0C,CC,CC,CC,78,00,00,00,00,00,00,E6,66,66,6C,78,78,6C,66,66,E6,00,00,00,00, +00,00,F0,60,60,60,60,60,60,62,66,FE,00,00,00,00,00,00,C6,EE,FE,FE,D6,C6,C6,C6,C6,C6,00,00,00,00, +00,00,C6,E6,F6,FE,DE,CE,C6,C6,C6,C6,00,00,00,00,00,00,7C,C6,C6,C6,C6,C6,C6,C6,C6,7C,00,00,00,00, +00,00,FC,66,66,66,7C,60,60,60,60,F0,00,00,00,00,00,00,7C,C6,C6,C6,C6,C6,C6,D6,DE,7C,0C,0E,00,00, +00,00,FC,66,66,66,7C,6C,66,66,66,E6,00,00,00,00,00,00,7C,C6,C6,60,38,0C,06,C6,C6,7C,00,00,00,00, +00,00,7E,7E,5A,18,18,18,18,18,18,3C,00,00,00,00,00,00,C6,C6,C6,C6,C6,C6,C6,C6,C6,7C,00,00,00,00, +00,00,C6,C6,C6,C6,C6,C6,C6,6C,38,10,00,00,00,00,00,00,C6,C6,C6,C6,D6,D6,D6,FE,EE,6C,00,00,00,00, +00,00,C6,C6,6C,7C,38,38,7C,6C,C6,C6,00,00,00,00,00,00,66,66,66,66,3C,18,18,18,18,3C,00,00,00,00, +00,00,FE,C6,86,0C,18,30,60,C2,C6,FE,00,00,00,00,00,00,3C,30,30,30,30,30,30,30,30,3C,00,00,00,00, +00,00,00,80,C0,E0,70,38,1C,0E,06,02,00,00,00,00,00,00,3C,0C,0C,0C,0C,0C,0C,0C,0C,3C,00,00,00,00, +10,38,6C,C6,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,FF,00,00, +30,30,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,78,0C,7C,CC,CC,CC,76,00,00,00,00, +00,00,E0,60,60,78,6C,66,66,66,66,7C,00,00,00,00,00,00,00,00,00,7C,C6,C0,C0,C0,C6,7C,00,00,00,00, +00,00,1C,0C,0C,3C,6C,CC,CC,CC,CC,76,00,00,00,00,00,00,00,00,00,7C,C6,FE,C0,C0,C6,7C,00,00,00,00, +00,00,38,6C,64,60,F0,60,60,60,60,F0,00,00,00,00,00,00,00,00,00,76,CC,CC,CC,CC,CC,7C,0C,CC,78,00, +00,00,E0,60,60,6C,76,66,66,66,66,E6,00,00,00,00,00,00,18,18,00,38,18,18,18,18,18,3C,00,00,00,00, +00,00,06,06,00,0E,06,06,06,06,06,06,66,66,3C,00,00,00,E0,60,60,66,6C,78,78,6C,66,E6,00,00,00,00, +00,00,38,18,18,18,18,18,18,18,18,3C,00,00,00,00,00,00,00,00,00,EC,FE,D6,D6,D6,D6,C6,00,00,00,00, +00,00,00,00,00,DC,66,66,66,66,66,66,00,00,00,00,00,00,00,00,00,7C,C6,C6,C6,C6,C6,7C,00,00,00,00, +00,00,00,00,00,DC,66,66,66,66,66,7C,60,60,F0,00,00,00,00,00,00,76,CC,CC,CC,CC,CC,7C,0C,0C,1E,00, +00,00,00,00,00,DC,76,66,60,60,60,F0,00,00,00,00,00,00,00,00,00,7C,C6,60,38,0C,C6,7C,00,00,00,00, +00,00,10,30,30,FC,30,30,30,30,36,1C,00,00,00,00,00,00,00,00,00,CC,CC,CC,CC,CC,CC,76,00,00,00,00, +00,00,00,00,00,66,66,66,66,66,3C,18,00,00,00,00,00,00,00,00,00,C6,C6,D6,D6,D6,FE,6C,00,00,00,00, +00,00,00,00,00,C6,6C,38,38,38,6C,C6,00,00,00,00,00,00,00,00,00,C6,C6,C6,C6,C6,C6,7E,06,0C,F8,00, +00,00,00,00,00,FE,CC,18,30,60,C6,FE,00,00,00,00,00,00,0E,18,18,18,70,18,18,18,18,0E,00,00,00,00, +00,00,18,18,18,18,00,18,18,18,18,18,00,00,00,00,00,00,70,18,18,18,0E,18,18,18,18,70,00,00,00,00, +00,00,76,DC,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,10,38,6C,C6,C6,C6,FE,00,00,00,00,00, +00,00,3C,66,C2,C0,C0,C0,C2,66,3C,0C,06,7C,00,00,00,00,CC,00,00,CC,CC,CC,CC,CC,CC,76,00,00,00,00, +00,0C,18,30,00,7C,C6,FE,C0,C0,C6,7C,00,00,00,00,00,10,38,6C,00,78,0C,7C,CC,CC,CC,76,00,00,00,00, +00,00,CC,00,00,78,0C,7C,CC,CC,CC,76,00,00,00,00,00,60,30,18,00,78,0C,7C,CC,CC,CC,76,00,00,00,00, +00,38,6C,38,00,78,0C,7C,CC,CC,CC,76,00,00,00,00,00,00,00,00,3C,66,60,60,66,3C,0C,06,3C,00,00,00, +00,10,38,6C,00,7C,C6,FE,C0,C0,C6,7C,00,00,00,00,00,00,C6,00,00,7C,C6,FE,C0,C0,C6,7C,00,00,00,00, +00,60,30,18,00,7C,C6,FE,C0,C0,C6,7C,00,00,00,00,00,00,66,00,00,38,18,18,18,18,18,3C,00,00,00,00, +00,18,3C,66,00,38,18,18,18,18,18,3C,00,00,00,00,00,60,30,18,00,38,18,18,18,18,18,3C,00,00,00,00, +00,C6,00,10,38,6C,C6,C6,FE,C6,C6,C6,00,00,00,00,38,6C,38,00,38,6C,C6,C6,FE,C6,C6,C6,00,00,00,00, +18,30,60,00,FE,66,60,7C,60,60,66,FE,00,00,00,00,00,00,00,00,00,CC,76,36,7E,D8,D8,6E,00,00,00,00, +00,00,3E,6C,CC,CC,FE,CC,CC,CC,CC,CE,00,00,00,00,00,10,38,6C,00,7C,C6,C6,C6,C6,C6,7C,00,00,00,00, +00,00,C6,00,00,7C,C6,C6,C6,C6,C6,7C,00,00,00,00,00,60,30,18,00,7C,C6,C6,C6,C6,C6,7C,00,00,00,00, +00,30,78,CC,00,CC,CC,CC,CC,CC,CC,76,00,00,00,00,00,60,30,18,00,CC,CC,CC,CC,CC,CC,76,00,00,00,00, +00,00,C6,00,00,C6,C6,C6,C6,C6,C6,7E,06,0C,78,00,00,C6,00,7C,C6,C6,C6,C6,C6,C6,C6,7C,00,00,00,00, +00,C6,00,C6,C6,C6,C6,C6,C6,C6,C6,7C,00,00,00,00,00,18,18,3C,66,60,60,60,66,3C,18,18,00,00,00,00, +00,38,6C,64,60,F0,60,60,60,60,E6,FC,00,00,00,00,00,00,66,66,3C,18,7E,18,7E,18,18,18,00,00,00,00, +00,F8,CC,CC,F8,C4,CC,DE,CC,CC,CC,C6,00,00,00,00,00,0E,1B,18,18,18,7E,18,18,18,18,18,D8,70,00,00, +00,18,30,60,00,78,0C,7C,CC,CC,CC,76,00,00,00,00,00,0C,18,30,00,38,18,18,18,18,18,3C,00,00,00,00, +00,18,30,60,00,7C,C6,C6,C6,C6,C6,7C,00,00,00,00,00,18,30,60,00,CC,CC,CC,CC,CC,CC,76,00,00,00,00, +00,00,76,DC,00,DC,66,66,66,66,66,66,00,00,00,00,76,DC,00,C6,E6,F6,FE,DE,CE,C6,C6,C6,00,00,00,00, +00,3C,6C,6C,3E,00,7E,00,00,00,00,00,00,00,00,00,00,38,6C,6C,38,00,7C,00,00,00,00,00,00,00,00,00, +00,00,30,30,00,30,30,60,C0,C6,C6,7C,00,00,00,00,00,00,00,00,00,00,FE,C0,C0,C0,C0,00,00,00,00,00, +00,00,00,00,00,00,FE,06,06,06,06,00,00,00,00,00,00,C0,C0,C2,C6,CC,18,30,60,DC,86,0C,18,3E,00,00, +00,C0,C0,C2,C6,CC,18,30,66,CE,9E,3E,06,06,00,00,00,00,18,18,00,18,18,18,3C,3C,3C,18,00,00,00,00, +00,00,00,00,00,36,6C,D8,6C,36,00,00,00,00,00,00,00,00,00,00,00,D8,6C,36,6C,D8,00,00,00,00,00,00, +11,44,11,44,11,44,11,44,11,44,11,44,11,44,11,44,55,AA,55,AA,55,AA,55,AA,55,AA,55,AA,55,AA,55,AA, +DD,77,DD,77,DD,77,DD,77,DD,77,DD,77,DD,77,DD,77,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,F8,18,18,18,18,18,18,18,18,18,18,18,18,18,F8,18,F8,18,18,18,18,18,18,18,18, +36,36,36,36,36,36,36,F6,36,36,36,36,36,36,36,36,00,00,00,00,00,00,00,FE,36,36,36,36,36,36,36,36, +00,00,00,00,00,F8,18,F8,18,18,18,18,18,18,18,18,36,36,36,36,36,F6,06,F6,36,36,36,36,36,36,36,36, +36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,00,00,00,00,00,FE,06,F6,36,36,36,36,36,36,36,36, +36,36,36,36,36,F6,06,FE,00,00,00,00,00,00,00,00,36,36,36,36,36,36,36,FE,00,00,00,00,00,00,00,00, +18,18,18,18,18,F8,18,F8,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,F8,18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,1F,00,00,00,00,00,00,00,00,18,18,18,18,18,18,18,FF,00,00,00,00,00,00,00,00, +00,00,00,00,00,00,00,FF,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,1F,18,18,18,18,18,18,18,18, +00,00,00,00,00,00,00,FF,00,00,00,00,00,00,00,00,18,18,18,18,18,18,18,FF,18,18,18,18,18,18,18,18, +18,18,18,18,18,1F,18,1F,18,18,18,18,18,18,18,18,36,36,36,36,36,36,36,37,36,36,36,36,36,36,36,36, +36,36,36,36,36,37,30,3F,00,00,00,00,00,00,00,00,00,00,00,00,00,3F,30,37,36,36,36,36,36,36,36,36, +36,36,36,36,36,F7,00,FF,00,00,00,00,00,00,00,00,00,00,00,00,00,FF,00,F7,36,36,36,36,36,36,36,36, +36,36,36,36,36,37,30,37,36,36,36,36,36,36,36,36,00,00,00,00,00,FF,00,FF,00,00,00,00,00,00,00,00, +36,36,36,36,36,F7,00,F7,36,36,36,36,36,36,36,36,18,18,18,18,18,FF,00,FF,00,00,00,00,00,00,00,00, +36,36,36,36,36,36,36,FF,00,00,00,00,00,00,00,00,00,00,00,00,00,FF,00,FF,18,18,18,18,18,18,18,18, +00,00,00,00,00,00,00,FF,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,3F,00,00,00,00,00,00,00,00, +18,18,18,18,18,1F,18,1F,00,00,00,00,00,00,00,00,00,00,00,00,00,1F,18,1F,18,18,18,18,18,18,18,18, +00,00,00,00,00,00,00,3F,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,FF,36,36,36,36,36,36,36,36, +18,18,18,18,18,FF,18,FF,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,F8,00,00,00,00,00,00,00,00, +00,00,00,00,00,00,00,1F,18,18,18,18,18,18,18,18,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF, +00,00,00,00,00,00,00,FF,FF,FF,FF,FF,FF,FF,FF,FF,F0,F0,F0,F0,F0,F0,F0,F0,F0,F0,F0,F0,F0,F0,F0,F0, +0F,0F,0F,0F,0F,0F,0F,0F,0F,0F,0F,0F,0F,0F,0F,0F,FF,FF,FF,FF,FF,FF,FF,00,00,00,00,00,00,00,00,00, +00,00,00,00,00,76,DC,D8,D8,D8,DC,76,00,00,00,00,00,00,78,CC,CC,CC,D8,CC,C6,C6,C6,CC,00,00,00,00, +00,00,FE,C6,C6,C0,C0,C0,C0,C0,C0,C0,00,00,00,00,00,00,00,00,FE,6C,6C,6C,6C,6C,6C,6C,00,00,00,00, +00,00,00,FE,C6,60,30,18,30,60,C6,FE,00,00,00,00,00,00,00,00,00,7E,D8,D8,D8,D8,D8,70,00,00,00,00, +00,00,00,00,66,66,66,66,66,7C,60,60,C0,00,00,00,00,00,00,00,76,DC,18,18,18,18,18,18,00,00,00,00, +00,00,00,7E,18,3C,66,66,66,3C,18,7E,00,00,00,00,00,00,00,38,6C,C6,C6,FE,C6,C6,6C,38,00,00,00,00, +00,00,38,6C,C6,C6,C6,6C,6C,6C,6C,EE,00,00,00,00,00,00,1E,30,18,0C,3E,66,66,66,66,3C,00,00,00,00, +00,00,00,00,00,7E,DB,DB,DB,7E,00,00,00,00,00,00,00,00,00,03,06,7E,DB,DB,F3,7E,60,C0,00,00,00,00, +00,00,1C,30,60,60,7C,60,60,60,30,1C,00,00,00,00,00,00,00,7C,C6,C6,C6,C6,C6,C6,C6,C6,00,00,00,00, +00,00,00,00,FE,00,00,FE,00,00,FE,00,00,00,00,00,00,00,00,00,18,18,7E,18,18,00,00,FF,00,00,00,00, +00,00,00,30,18,0C,06,0C,18,30,00,7E,00,00,00,00,00,00,00,0C,18,30,60,30,18,0C,00,7E,00,00,00,00, +00,00,0E,1B,1B,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,D8,D8,D8,70,00,00,00,00, +00,00,00,00,18,18,00,7E,00,18,18,00,00,00,00,00,00,00,00,00,00,76,DC,00,76,DC,00,00,00,00,00,00, +00,38,6C,6C,38,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,18,18,00,00,00,00,00,00,00, +00,00,00,00,00,00,00,00,18,00,00,00,00,00,00,00,00,0F,0C,0C,0C,0C,0C,EC,6C,6C,3C,1C,00,00,00,00, +00,D8,6C,6C,6C,6C,6C,00,00,00,00,00,00,00,00,00,00,70,D8,30,60,C8,F8,00,00,00,00,00,00,00,00,00, +00,00,00,00,7C,7C,7C,7C,7C,7C,7C,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00; \ No newline at end of file Index: HW/KB_8042.v =================================================================== --- HW/KB_8042.v (nonexistent) +++ HW/KB_8042.v (revision 2) @@ -0,0 +1,239 @@ +////////////////////////////////////////////////////////////////////////////////// +// +// This file is part of the Next186 Soc PC project +// http://opencores.org/project,next186 +// +// Filename: KB_8042.v +// Description: Part of the Next186 SoC PC project, keyboard/mouse PS2 controller +// Simplified 8042 implementation +// Version 1.0 +// Creation date: Jan2013 +// +// Author: Nicolae Dumitrache +// e-mail: ndumitrache@opencores.org +// +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2013 Nicolae Dumitrache +// +// This source file may be used and distributed without +// restriction provided that this copyright statement is not +// removed from the file and that any derivative work contains +// the original copyright notice and the associated disclaimer. +// +// This source file is free software; you can redistribute it +// and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; +// either version 2.1 of the License, or (at your option) any +// later version. +// +// This source is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General +// Public License along with this source; if not, download it +// from http://www.opencores.org/lgpl.shtml +// +/////////////////////////////////////////////////////////////////////////////////// +// Additional Comments: +// +// http://www.computer-engineering.org/ps2keyboard/ +// http://wiki.osdev.org/%228042%22_PS/2_Controller +// http://wiki.osdev.org/Mouse_Input +// +// Primary connection +// NET "PS2_CLK1" LOC = "W12" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; +// NET "PS2_DATA1" LOC = "V11" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; +// Secondary connection (requires Y-splitter cable) +// NET "PS2_CLK2" LOC = "U11" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; +// NET "PS2_DATA2" LOC = "Y12" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; +////////////////////////////////////////////////////////////////////////////////// +`timescale 1ns / 1ps + +module KB_Mouse_8042( + input CS, + input WR, + input cmd, // 0x60 = data, 0x64 = cmd + input [7:0]din, + output [7:0]dout, + input clk, // cpu CLK + output I_KB, // interrupt keyboard + output I_MOUSE, // interrupt mouse + output reg CPU_RST = 0, + inout PS2_CLK1, + inout PS2_CLK2, + inout PS2_DATA1, + inout PS2_DATA2 + ); + +// status bit5 = MOBF (mouse to host buffer full - with OBF), bit4=INH, bit2(1-initialized ok), bit1(IBF-input buffer full - host to kb/mouse), bit0(OBF-output buffer full - kb/mouse to host) + reg [3:0]cmdbyte = 4'b1100; // EN2,EN,INT2,INT + reg wcfg = 0; // write config byte + reg next_mouse = 0; + reg ctl_outb = 0; + reg [9:0]wr_data; + reg [7:0]clkdiv128 = 0; + reg [7:0]cnt100us = 0; // single delay counter for both kb and mouse + reg wr_mouse = 0; + reg wr_kb = 0; + reg rd_kb = 0; + reg rd_mouse = 0; + reg OBF = 0; + reg MOBF = 0; + reg [7:0]s_data; + + wire [7:0]kb_data; + wire [7:0]mouse_data; + wire kb_data_out_ready; + wire kb_data_in_ready; + wire mouse_data_out_ready; + wire mouse_data_in_ready; + wire IBF = ((wr_kb | ~kb_data_in_ready) & ~cmdbyte[2]) | ((wr_mouse | ~mouse_data_in_ready) & ~cmdbyte[3]); + wire kb_shift; + wire mouse_shift; + + assign dout = cmd ? {2'b00, MOBF, 1'b1, wcfg, 1'b1, IBF, OBF | MOBF | ctl_outb} : ctl_outb ? {2'b00, cmdbyte[3:2], 2'b00, cmdbyte[1:0]} : s_data; //MOBF ? mouse_data : kb_data; + assign I_KB = cmdbyte[0] & OBF; // INT & OBF + assign I_MOUSE = cmdbyte[1] & MOBF; // INT2 & MOBF + + PS2Interface Keyboard + ( + .PS2_CLK(PS2_CLK1), + .PS2_DATA(PS2_DATA1), + .clk(clk), + .rd(rd_kb), + .wr(wr_kb), + .data_in(wr_data[0]), + .data_out(kb_data), + .data_out_ready(kb_data_out_ready), + .data_in_ready(kb_data_in_ready), + .delay100us(cnt100us[7]), + .data_shift(kb_shift), + .clk_sample(clkdiv128[7]) + ); + + PS2Interface Mouse + ( + .PS2_CLK(PS2_CLK2), + .PS2_DATA(PS2_DATA2), + .clk(clk), + .rd(rd_mouse), + .wr(wr_mouse), + .data_in(wr_data[0]), + .data_out(mouse_data), + .data_out_ready(mouse_data_out_ready), + .data_in_ready(mouse_data_in_ready), + .delay100us(cnt100us[7]), + .data_shift(mouse_shift), + .clk_sample(clkdiv128[7]) + ); + + always @(posedge clk) begin + CPU_RST <= 0; + if(~kb_data_in_ready) wr_kb <= 0; + if(~kb_data_out_ready) rd_kb <= 1'b0; + if(~mouse_data_in_ready) wr_mouse <= 0; + if(~mouse_data_out_ready) rd_mouse <= 1'b0; + + clkdiv128 <= clkdiv128[6:0] + 1'b1; + if(CS & WR & ~cmd & ~wcfg) cnt100us <= 0; // reset 100us counter for PS2 writing + else if(!cnt100us[7] & clkdiv128[7]) cnt100us <= cnt100us + 1; + + + if(~OBF & ~MOBF) + if(kb_data_out_ready & ~rd_kb & ~cmdbyte[2]) begin + OBF <= 1'b1; + s_data <= kb_data; + end else if(mouse_data_out_ready & ~rd_mouse & ~cmdbyte[3]) begin + MOBF <= 1'b1; + s_data <= mouse_data; + end + + if(kb_shift | mouse_shift) wr_data <= {1'b1, wr_data[9:1]}; + + if(CS) + if(WR) + if(cmd) // 0x64 write + case(din) + 8'h20: ctl_outb <= 1; // read config byte + 8'h60: wcfg <= 1; // write config byte + 8'ha7: cmdbyte[3] <= 1; // disable mouse + 8'ha8: cmdbyte[3] <= 0; // enable mouse + 8'had: cmdbyte[2] <= 1; // disable kb + 8'hae: cmdbyte[2] <= 0; // enable kb + 8'hd4: next_mouse <= 1; // write next byte to mouse + /*8'hf0, 8'hf2, 8'hf4, 8'hf6, 8'hf8, 8'hfa, 8'hfc,*/ 8'hfe: CPU_RST <= 1; // CPU reset + endcase + else begin // 0x60 write + if(wcfg) cmdbyte <= {din[5:4], din[1:0]}; + else begin + next_mouse <= 0; + wr_mouse <= next_mouse; + wr_kb <= ~next_mouse; + wr_data <= {~^din, din, 1'b0}; +// cnt100us <= 0; // reset 100us counter for PS2 writing + end + wcfg <= 0; + end + else // read data + if(~cmd) begin + ctl_outb <= 1'b0; + if(!ctl_outb) begin + OBF <= 1'b0; + MOBF <= 1'b0; + rd_kb <= OBF; + rd_mouse <= MOBF; + end + end + end +endmodule + + +module PS2Interface( + inout PS2_CLK, + inout PS2_DATA, + input clk, + input rd, // enable PS2 data reading + input wr, // can write data from controller to PS2 + input data_in, // data from controller + input delay100us, + output [7:0]data_out, // data from PS2 + output reg data_out_ready = 1, // PS2 received data ready + output reg data_in_ready = 1, // PS2 sent data ready + output data_shift, + input clk_sample + ); + reg [1:0]s_clk = 2'b11; + reg [9:0]data = 0; + reg rd_progress = 0; + reg s_ps2_clk = 1'b1; + + assign PS2_CLK = ((~data_out_ready & data_in_ready) | (~data_in_ready & delay100us)) ? 1'bz : 1'b0; + assign PS2_DATA = (data_in_ready | data_in | ~delay100us) ? 1'bz : 1'b0; + assign data_out = data[7:0]; + assign data_shift = ~data_in_ready && delay100us && s_clk == 2'b10; + + always @(posedge clk) begin + if(clk_sample) s_ps2_clk <= PS2_CLK; // debounce PS2 clock + s_clk <= {s_clk[0], s_ps2_clk}; + if(data_out_ready) rd_progress <= 1'b0; + + if(~data_in_ready) begin // send data to PS2 + if(data_shift) data_in_ready <= data_in ^ PS2_DATA; + end else if(wr && ~rd_progress) begin // initiate data sending to PS2 + data_in_ready <= 1'b0; + end else if(~data_out_ready) begin // receive data from PS2 + if(s_clk == 2'b10) begin + rd_progress <= 1'b1; + if(!rd_progress) data <= 10'b1111111111; + end + if(s_clk == 2'b01 && rd_progress) {data, data_out_ready} <= {PS2_DATA, data[9:1], ~data[0]}; // receive is ended by the stop bit + end else if(rd) begin // initiate data receiving from PS2 +// data <= 10'b1111111111; + data_out_ready <= 1'b0; + end + end +endmodule

powered by: WebSVN 2.1.0

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