use 2 ram banks, attempt to make SDRAM work
This commit is contained in:
parent
7f0d9280ca
commit
c360c6ee7f
|
@ -117,7 +117,6 @@ wire pll_locked;
|
|||
|
||||
wire sys_clock; // cpu x 7 x 8 system clock (sdram.v)
|
||||
wire osd_clock; // cpu x 7 x 2 for the OSD menu
|
||||
wire sdram_clock_ph; // cpu x 7 x 8 phase shifted -2.5 ns
|
||||
|
||||
pll pll
|
||||
(
|
||||
|
@ -126,7 +125,7 @@ pll pll
|
|||
|
||||
.c0( osd_clock ), // cpu x 7 x 2 video clock for OSD menu
|
||||
.c2( sys_clock ), // cpu x 7 x 8 system clock (sdram.v)
|
||||
.c3( sdram_clock_ph ) // cpu x 7 x 8 phase shifted -2.5 ns
|
||||
.c3( SDRAM_CLK ) // cpu x 7 x 8 phase shifted -2.5 ns
|
||||
);
|
||||
|
||||
/******************************************************************************************/
|
||||
|
@ -173,55 +172,21 @@ downloader
|
|||
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
/***************************************** @apple1 ****************************************/
|
||||
/***************************************** @ram *******************************************/
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
|
||||
// RAM
|
||||
ram ram(
|
||||
wire [7:0] ram_dout;
|
||||
|
||||
// low system RAM
|
||||
ram #(.SIZE(16384)) ram(
|
||||
.clk (sys_clock ),
|
||||
.ena (cpu_clken ), // fake does not work
|
||||
.address(sdram_addr[15:0]),
|
||||
.w_en (sdram_wr ),
|
||||
.w_en (sdram_wr & ram_cs),
|
||||
.din (sdram_din ),
|
||||
.dout (sdram_dout)
|
||||
.dout (ram_dout )
|
||||
);
|
||||
|
||||
// SDRAM control signals
|
||||
|
||||
wire [24:0] sdram_addr;
|
||||
wire [7:0] sdram_din;
|
||||
wire sdram_wr;
|
||||
wire sdram_rd;
|
||||
wire [7:0] sdram_dout;
|
||||
|
||||
assign dummy = is_downloading && download_wr;
|
||||
|
||||
always @(*) begin
|
||||
if(is_downloading && download_wr) begin
|
||||
sdram_addr <= download_addr;
|
||||
sdram_din <= download_data;
|
||||
sdram_wr <= download_wr;
|
||||
sdram_rd <= 1'b1;
|
||||
end
|
||||
/*
|
||||
else if(eraser_busy) begin
|
||||
sdram_addr <= eraser_addr;
|
||||
sdram_din <= eraser_data;
|
||||
sdram_wr <= eraser_wr;
|
||||
sdram_rd <= 1'b1;
|
||||
end
|
||||
*/
|
||||
else begin
|
||||
sdram_addr <= { 9'b0, cpu_addr[15:0] };
|
||||
sdram_din <= cpu_dout;
|
||||
sdram_wr <= cpu_wr;
|
||||
sdram_rd <= cpu_rd;
|
||||
end
|
||||
end
|
||||
|
||||
assign LED = ~dummy;
|
||||
|
||||
// WozMon ROM
|
||||
wire [7:0] rom_dout;
|
||||
rom_wozmon rom_wozmon(
|
||||
|
@ -230,6 +195,7 @@ rom_wozmon rom_wozmon(
|
|||
.dout(rom_dout)
|
||||
);
|
||||
|
||||
/*
|
||||
// Basic ROM
|
||||
wire [7:0] basic_dout;
|
||||
rom_basic rom_basic(
|
||||
|
@ -237,6 +203,51 @@ rom_basic rom_basic(
|
|||
.address(cpu_addr[11:0]),
|
||||
.dout(basic_dout)
|
||||
);
|
||||
*/
|
||||
|
||||
// Basic RAM
|
||||
wire [7:0] basic_dout;
|
||||
ram #(.SIZE(4096)) rom_basic(
|
||||
.clk(sys_clock),
|
||||
.address({4'b000, sdram_addr[11:0]}),
|
||||
.w_en (sdram_wr & basic_cs),
|
||||
.din (sdram_din ),
|
||||
.dout (basic_dout)
|
||||
);
|
||||
|
||||
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
/***************************************** @apple1 ****************************************/
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
|
||||
// SDRAM control signals
|
||||
|
||||
wire [24:0] sdram_addr;
|
||||
wire [7:0] sdram_din;
|
||||
wire sdram_wr;
|
||||
wire sdram_rd;
|
||||
wire [7:0] sdram_dout;
|
||||
|
||||
always @(*) begin
|
||||
if(is_downloading && download_wr) begin
|
||||
sdram_addr <= download_addr;
|
||||
sdram_din <= download_data;
|
||||
sdram_wr <= download_wr;
|
||||
sdram_rd <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
sdram_addr <= { 9'b0, cpu_addr[15:0] };
|
||||
sdram_din <= cpu_dout;
|
||||
sdram_wr <= cpu_wr;
|
||||
sdram_rd <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
wire dummy = is_downloading && download_wr;
|
||||
assign LED = ~dummy;
|
||||
|
||||
|
||||
// ram interface
|
||||
wire [15:0] cpu_addr;
|
||||
|
@ -244,13 +255,15 @@ wire [7:0] cpu_dout;
|
|||
wire cpu_rd;
|
||||
wire cpu_wr;
|
||||
|
||||
wire ram_cs = cpu_addr < 16'hc000; // 0x0000 -> 0x1FFF
|
||||
wire basic_cs = cpu_addr >= 16'hE000 && cpu_addr <= 16'hEFFF; // 0xE000 -> 0xEFFF
|
||||
wire rom_cs = cpu_addr >= 16'hFF00 && cpu_addr <= 16'hFFFF; // 0xFF00 -> 0xFFFF
|
||||
wire ram_cs = sdram_addr < 'h4000; // 0x0000 -> 0x3FFF
|
||||
wire sdram_cs = sdram_addr >= 'h4000 && sdram_addr <= 'hBFFF; // 0x4000 -> 0xBFFF
|
||||
wire basic_cs = sdram_addr >= 'hE000 && sdram_addr <= 'hEFFF; // 0xE000 -> 0xEFFF
|
||||
wire rom_cs = sdram_addr >= 'hFF00; // 0xFF00 -> 0xFFFF
|
||||
|
||||
wire [7:0] bus_dout = basic_cs ? basic_dout :
|
||||
rom_cs ? rom_dout :
|
||||
ram_cs ? sdram_dout :
|
||||
wire [7:0] bus_dout = rom_cs ? rom_dout :
|
||||
basic_cs ? basic_dout :
|
||||
sdram_cs ? sdram_dout :
|
||||
ram_cs ? ram_dout :
|
||||
8'b0;
|
||||
|
||||
apple1 apple1
|
||||
|
@ -324,7 +337,7 @@ mist_video
|
|||
.VGA_G(VGA_G),
|
||||
.VGA_B(VGA_B),
|
||||
.VGA_VS(VGA_VS),
|
||||
.VGA_HS(VGA_HS),
|
||||
.VGA_HS(VGA_HS)
|
||||
);
|
||||
|
||||
/******************************************************************************************/
|
||||
|
@ -368,7 +381,6 @@ user_io (
|
|||
|
||||
// SDRAM control signals
|
||||
assign SDRAM_CKE = 1'b1;
|
||||
assign SDRAM_CLK = sdram_clock_ph; // same as sys_clock but with -2.5 ns phase
|
||||
|
||||
/*
|
||||
wire [24:0] sdram_addr;
|
||||
|
@ -397,6 +409,7 @@ always @(*) begin
|
|||
sdram_rd <= cpu_rd;
|
||||
end
|
||||
end
|
||||
*/
|
||||
|
||||
sdram sdram (
|
||||
// interface to the MT48LC16M16 chip
|
||||
|
@ -412,8 +425,8 @@ sdram sdram (
|
|||
// system interface
|
||||
.clk ( sys_clock ),
|
||||
.clkref ( cpu_clock ),
|
||||
.init ( !pll_locked ),
|
||||
|
||||
.init ( !pll_locked ),
|
||||
|
||||
// cpu interface
|
||||
.din ( sdram_din ),
|
||||
.addr ( sdram_addr ),
|
||||
|
@ -421,21 +434,22 @@ sdram sdram (
|
|||
.oe ( sdram_rd ),
|
||||
.dout ( sdram_dout )
|
||||
);
|
||||
*/
|
||||
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
/***************************************** @clock_ena *************************************/
|
||||
/***************************************** @clock *****************************************/
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
|
||||
wire cpu_clken; // provides the cpu clock enable signal derived from main clock
|
||||
wire pixel_clken; // provides the cpu clock enable signal derived from main clock
|
||||
wire cpu_clock;
|
||||
|
||||
clock clock(
|
||||
.sys_clock ( sys_clock ), // input: main clock
|
||||
.sys_clock ( sys_clock ), // input: main clock
|
||||
.reset ( reset_button ), // input: reset signal
|
||||
|
||||
|
||||
.cpu_clock ( cpu_clock ),
|
||||
.cpu_clken ( cpu_clken ), // output: cpu clock enable
|
||||
.pixel_clken( pixel_clken ) // output: pixel clock enable
|
||||
);
|
||||
|
|
|
@ -5,7 +5,9 @@ module clock
|
|||
input reset, // reset
|
||||
|
||||
output cpu_clken, // 1MHz clock enable for the CPU
|
||||
output pixel_clken // 7MHz clock enable for the display
|
||||
output pixel_clken, // 7MHz clock enable for the display
|
||||
|
||||
output cpu_clock
|
||||
);
|
||||
|
||||
localparam CPU_DIVISOR = 56; // (sys_clock / CPU_DIVISOR) = 1 MHz
|
||||
|
@ -27,10 +29,13 @@ localparam PIXEL_DIVISOR = 8; // (sys_clock / PIXEL_DIVISOR) = 7 MHz
|
|||
|
||||
if (counter_pixel == (PIXEL_DIVISOR-1)) counter_pixel <= 0;
|
||||
else counter_pixel <= counter_pixel + 1;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
assign cpu_clken = counter_cpu == 0;
|
||||
assign pixel_clken = counter_pixel == 0;
|
||||
|
||||
|
||||
assign cpu_clock = counter_pixel < 4 ? 1 : 0;
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -266,12 +266,12 @@ endmodule
|
|||
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT3 STRING "-2.50000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT3 STRING "-2500.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "ps"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT3 STRING "ns"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT3 STRING "ps"
|
||||
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
|
||||
|
|
78
rtl/sdram.v
78
rtl/sdram.v
|
@ -24,10 +24,10 @@ module sdram (
|
|||
|
||||
// interface to the MT48LC16M16 chip
|
||||
inout [15:0] sd_data, // 16 bit bidirectional data bus
|
||||
output [12:0] sd_addr, // 13 bit multiplexed address bus
|
||||
output [12:0] sd_addr, // 13 bit multiplexed address bus for row/col select
|
||||
output [1:0] sd_dqm, // two byte masks
|
||||
output [1:0] sd_ba, // two banks
|
||||
output sd_cs, // a single chip select
|
||||
output [1:0] sd_ba, // four banks
|
||||
output sd_cs, // chip select
|
||||
output sd_we, // write enable
|
||||
output sd_ras, // row address select
|
||||
output sd_cas, // columns address select
|
||||
|
@ -37,6 +37,8 @@ module sdram (
|
|||
input clk, // sdram is accessed at up to 128MHz
|
||||
input clkref, // reference clock to sync to
|
||||
|
||||
// input [2:0] q,
|
||||
|
||||
input [7:0] din, // data input from chipset/cpu
|
||||
output [7:0] dout, // data output to chipset/cpu
|
||||
input [24:0] addr, // 25 bit byte address
|
||||
|
@ -44,26 +46,33 @@ module sdram (
|
|||
input we // cpu/chipset requests write
|
||||
);
|
||||
|
||||
// no burst configured
|
||||
// ---------------------------------------------------------------------
|
||||
// ------------------------ sdram configuration ------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
// MODE is sent as address on reset = 2
|
||||
// PRECHARGE_ADDR is sent as address on reset = 13
|
||||
localparam RASCAS_DELAY = 3'd3; // tRCD>=20ns -> 2 cycles@64MHz
|
||||
localparam BURST_LENGTH = 3'b000; // 000=none, 001=2, 010=4, 011=8
|
||||
localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
|
||||
localparam CAS_LATENCY = 3'd2; // 2/3 allowed
|
||||
localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
|
||||
localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write
|
||||
|
||||
localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
|
||||
localparam PRECHARGE_ADDR = 13'b0010000000000;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// ------------------------ cycle state machine ------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
localparam STATE_IDLE = 3'd0; // first state in cycle
|
||||
localparam STATE_CMD_START = 3'd1; // state in which a new command can be started
|
||||
localparam STATE_CMD_CONT = STATE_CMD_START + RASCAS_DELAY - 3'd1; // 4 command can be continued
|
||||
localparam STATE_LAST = 3'd7; // last state in cycle
|
||||
// there are 8 states (0-7) tracked by "q"
|
||||
|
||||
localparam STATE_IDLE = 3'd0; // first state in cycle
|
||||
localparam STATE_CMD_START = 3'd1; // state in which a new command can be started
|
||||
localparam STATE_CMD_CONT = STATE_CMD_START+RASCAS_DELAY-3'd1; // 4 command can be continued
|
||||
localparam STATE_LAST = 3'd7; // last state in cycle
|
||||
|
||||
reg [2:0] q /* synthesis noprune */;
|
||||
|
||||
always @(posedge clk) begin
|
||||
// 32Mhz counter synchronous to 4 Mhz clock
|
||||
// force counter to pass state 5->6 exactly after the rising edge of clkref
|
||||
|
@ -74,6 +83,7 @@ always @(posedge clk) begin
|
|||
q <= q + 3'd1;
|
||||
end
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// --------------------------- startup/reset ---------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
@ -92,25 +102,25 @@ end
|
|||
// ---------------------------------------------------------------------
|
||||
|
||||
// all possible commands
|
||||
localparam CMD_INHIBIT = 4'b1111;
|
||||
localparam CMD_NOP = 4'b0111;
|
||||
localparam CMD_ACTIVE = 4'b0011;
|
||||
localparam CMD_READ = 4'b0101;
|
||||
localparam CMD_WRITE = 4'b0100;
|
||||
localparam CMD_BURST_TERMINATE = 4'b0110;
|
||||
localparam CMD_PRECHARGE = 4'b0010;
|
||||
localparam CMD_AUTO_REFRESH = 4'b0001;
|
||||
localparam CMD_LOAD_MODE = 4'b0000;
|
||||
localparam CMD_INHIBIT = 4'b1111; // initial state
|
||||
localparam CMD_NOP = 4'b0111; // (not used here)
|
||||
localparam CMD_ACTIVE = 4'b0011; // command starts, done at STATE_IDLE
|
||||
localparam CMD_READ = 4'b0101; // read commanddone, done at STATE_CMD_CONT
|
||||
localparam CMD_WRITE = 4'b0100; // write command, done at STATE_CMD_CONT
|
||||
localparam CMD_BURST_TERMINATE = 4'b0110; // (not used here)
|
||||
localparam CMD_PRECHARGE = 4'b0010; // sends a precharge address, done when reset=13 and STATE_IDLE
|
||||
localparam CMD_AUTO_REFRESH = 4'b0001; // refresh command, done at STATE_IDLE
|
||||
localparam CMD_LOAD_MODE = 4'b0000; // sends MODE (sdram config), done when reset=2 and STATE_IDLE
|
||||
|
||||
reg [3:0] sd_cmd; // current command sent to sd ram
|
||||
|
||||
// drive control signals according to current command
|
||||
assign sd_cs = sd_cmd[3];
|
||||
assign sd_ras = sd_cmd[2];
|
||||
assign sd_cas = sd_cmd[1];
|
||||
assign sd_we = sd_cmd[0];
|
||||
assign sd_cs = sd_cmd[3]; // in negated logic
|
||||
assign sd_ras = sd_cmd[2]; // in negated logic
|
||||
assign sd_cas = sd_cmd[1]; // in negated logic
|
||||
assign sd_we = sd_cmd[0]; // in negated logic
|
||||
|
||||
assign sd_data = we?{din, din}:16'bZZZZZZZZZZZZZZZZ;
|
||||
assign sd_data = we ? {din, din} : 16'bZZZZZZZZZZZZZZZZ;
|
||||
|
||||
assign dout = sd_data[7:0];
|
||||
|
||||
|
@ -118,30 +128,34 @@ always @(posedge clk) begin
|
|||
sd_cmd <= CMD_INHIBIT;
|
||||
|
||||
if(reset != 0) begin
|
||||
// SDRAM is resetting, counting from 31 to 0
|
||||
if(q == STATE_IDLE) begin
|
||||
if(reset == 13) sd_cmd <= CMD_PRECHARGE;
|
||||
if(reset == 2) sd_cmd <= CMD_LOAD_MODE;
|
||||
end
|
||||
end else begin
|
||||
// normal run
|
||||
if(q == STATE_IDLE) begin
|
||||
if(we || oe) sd_cmd <= CMD_ACTIVE;
|
||||
else sd_cmd <= CMD_AUTO_REFRESH;
|
||||
end else if(q == STATE_CMD_CONT) begin
|
||||
end
|
||||
else if(q == STATE_CMD_CONT) begin
|
||||
if(we) sd_cmd <= CMD_WRITE;
|
||||
else if(oe) sd_cmd <= CMD_READ;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire [12:0] reset_addr = (reset == 13)?13'b0010000000000:MODE;
|
||||
|
||||
wire [12:0] run_addr =
|
||||
(q == STATE_CMD_START)?addr[20:8]:{ 4'b0010, addr[23], addr[7:0]};
|
||||
|
||||
assign sd_addr = (reset != 0)?reset_addr:run_addr;
|
||||
// address during reset
|
||||
wire [12:0] reset_addr = (reset == 13) ? PRECHARGE_ADDR : MODE;
|
||||
|
||||
assign sd_ba = addr[22:21];
|
||||
// address during normal run
|
||||
wire [12:0] row = addr[20:8];
|
||||
wire [12:0] col = { 4'b0010, addr[23], addr[7:0] };
|
||||
wire [12:0] run_addr = (q == STATE_CMD_START)? row : col;
|
||||
|
||||
assign sd_dqm = 2'b00;
|
||||
assign sd_addr = (reset != 0) ? reset_addr : run_addr;
|
||||
assign sd_ba = addr[22:21]; // bank is taken from cpu address high bits
|
||||
assign sd_dqm = 2'b00; // no mask
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Reference in New Issue