1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-01-31 21:42:20 +00:00

Simplified sdram controller

This commit is contained in:
harbaum
2013-10-31 16:10:52 +00:00
parent a645905f81
commit b73795648b
9 changed files with 193 additions and 838 deletions

View File

@@ -164,8 +164,8 @@ BEGIN
-- sel_fast <= '1' when cpuaddr(23 downto 21)="001" OR cpuaddr(23 downto 21)="010" ELSE '0'; --$200000 - $5FFFFF
-- sel_fast <= '1' when cpuaddr(23 downto 19)="11111" ELSE '0'; --$F800000;--
-- sel_fast <= '0'; -- off
sel_fast <= '1' when turbo='1' AND cpuaddr(23 downto 22)="00" AND state/="01" ELSE '0'; --$000000 - $3fffff
sel_fast <= '0'; -- off
-- sel_fast <= '1' when turbo='1' AND cpuaddr(23 downto 22)="00" AND state/="01" ELSE '0'; --$000000 - $3fffff
-- sel_fast <= '1' when (cpuaddr(23 downto 22)="00" OR cpuaddr(23 downto 17)="1111110" OR cpuaddr(23 downto 16)="11111110" OR cpuaddr(23 downto 17)="1111101" OR cpuaddr(23 downto 18)="111000") AND state/="01" ELSE '0'; --$000000 - $3fffff
ramcs <= (NOT sel_fast) or slower(0);-- OR (state(0) AND NOT state(1));

View File

@@ -24,10 +24,11 @@ module data_io (
// ram interface
output reg [2:0] state, // state bits required to drive the sdram host
output reg read,
output reg write,
output [22:0] addr,
output reg [15:0] data_out, // write data register
input [15:0] data_in,
input ack
input [15:0] data_in
);
assign dma_idx = bcnt;
@@ -37,35 +38,51 @@ reg [4:0] bcnt; // payload byte counter
reg [14:0] sbuf; // receive buffer (buffer used to assemble spi bytes/words)
reg [7:0] cmd; // command byte (first byte of spi transmission)
reg [30:0] addrR;// address register (word address for memory transfers)
reg write; // write request received via SPI
reg writeCmd; // write request received via SPI
reg writeD; // write synchonized to 8Mhz clock
reg writeD2; // synchronized write delayed by one 8Mhz clock
reg read; // read request received via SPI
reg readCmd; // read request received via SPI
reg readD; // read synchonized to 8Mhz clock
reg readD2; // synchronized read delayed by one 8Mhz clock
reg [15:0] ram_data; // latch for incoming ram data
reg brI; // signals to bring br into local clock domain
// during write the address needs to be decremented by one as the
// address auto increment takes place at the beginning of each transfer
assign addr = addrR[22:0] - ((cmd == 2)?23'b1:23'b0);
assign addr = (cmd==2)?(addrR[22:0]-23'd1):addrR[22:0];
// generate state signals required to control the sdram host interface
always @(posedge clk_8) begin
// start io transfers clock cycles after bus_cycle 0
// (after the cpu cycle)
writeD <= write && ((bus_cycle == 3) || writeD);
// (after the cpu cycle)
writeD <= writeCmd && ((bus_cycle == 3) || writeD);
writeD2 <= writeD;
readD <= read && ((bus_cycle == 3) || readD);
readD <= readCmd && ((bus_cycle == 3) || readD);
readD2 <= readD;
if(reset)
br <= brI;
// at the end of a read cycle latch the incoming ram data for later spi transmission
if(read) ram_data <= data_in;
if(reset) begin
state <= 3'b101;
else begin
if(writeD && ~writeD2)
state <= 3'b011; // write data
else if(readD && ~readD2)
state <= 3'b010; // read data
else
state <= 3'b001; // decode (idle)
read <= 1'b0;
write <= 1'b0;
end else begin
if(writeD && ~writeD2) begin
// state <= 3'b011; // write data
write <= 1'b1;
read <= 1'b0;
end else if(readD && ~readD2) begin
// state <= 3'b010; // read data
write <= 1'b0;
read <= 1'b1;
end else begin
// state <= 3'b001; // decode (idle)
write <= 1'b0;
read <= 1'b0;
end
end
end
@@ -76,7 +93,7 @@ always@(negedge sck) begin
// memory read
if(cmd == 3) begin
if(cnt == 8)
txData <= data_in;
txData <= ram_data;
else
txData[15:1] <= txData[14:0];
end
@@ -90,12 +107,13 @@ always@(negedge sck) begin
end
end
always@(posedge sck, posedge ss) begin
if(ss == 1'b1) begin
cnt <= 5'd0;
bcnt <= 4'd0;
write <= 1'b0;
read <= 1'b0;
writeCmd <= 1'b0;
readCmd <= 1'b0;
dma_ack <= 1'b0;
end else begin
dma_ack <= 1'b0;
@@ -120,15 +138,15 @@ always@(posedge sck, posedge ss) begin
// request bus
if({sbuf[6:0], sdi } == 8'd7)
br <= 1'b1;
brI <= 1'b1;
// release bus
if({sbuf[6:0], sdi } == 8'd8)
br <= 1'b0;
brI <= 1'b0;
// if we can see a read coming initiate sdram read transfer asap
if({sbuf[6:0], sdi } == 8'd3)
read <= 1;
readCmd <= 1;
end
// handle "payload"
@@ -141,23 +159,23 @@ always@(posedge sck, posedge ss) begin
// write ram
if(cmd == 2) begin
if(cnt == 5'd16)
write <= 1'b0;
writeCmd <= 1'b0;
if(cnt == 5'd23) begin
data_out <= { sbuf, sdi };
addrR <= addrR + 31'b1;
write <= 1'b1;
writeCmd <= 1'b1;
end
end
// read ram
if(cmd == 3) begin
if(cnt == 16)
read <= 0;
readCmd <= 0;
if(cnt == 23) begin
addrR <= addrR + 31'b1;
read <= 1;
readCmd <= 1;
end
end

View File

@@ -258,22 +258,20 @@ always @(negedge clk) begin
end
if(din[7:5] == 3'b101) // write sector
if(!fdc_wr_prot) begin
if(!fdc_wr_prot)
fdc_busy <= 2'd3;
end
// ------------- TYPE III commands ------------
// these aren't supported yet
// if(din[7:4] == 4'b1100) // read address
// fdc_busy <= 2'd3;
if(din[7:4] == 4'b1100) // read address
fdc_busy <= 2'd3;
// if(din[7:4] == 4'b1110) // read track
// fdc_busy <= 2'd3;
if(din[7:4] == 4'b1110) // read track
fdc_busy <= 2'd3;
// if(din[7:4] == 4'b1111) // write track
// if(!fdc_wr_prot)
// fdc_busy <= 2'd3;
if(din[7:4] == 4'b1111) // write track
if(!fdc_wr_prot)
fdc_busy <= 2'd3;
// ------------- TYPE IV commands -------------
if(din[7:4] == 4'b1101) // force intrerupt

View File

@@ -1,10 +1,5 @@
//
// TODO:
// - map remaining inputs to irqs
// - implement pulse mode
// - suppress input irqs when timer_a/b are in event or pulse mode
module mfp (
// cpu register interface
input clk,
@@ -60,10 +55,12 @@ reg [13:0] readTimer;
wire write = sel && ~ds && ~rw;
// timer a/b is in pulse mode
wire [1:0] pulse_mode;
wire timera_done;
wire [7:0] timera_dat_o;
wire [4:0] timera_ctrl_o;
wire i4_irq_disable;
mfp_timer timer_a (
.CLK (clk),
@@ -75,7 +72,7 @@ mfp_timer timer_a (
.DAT_I (din),
.DAT_O (timera_dat_o),
.DAT_WE ((addr == 5'h0f) && write),
.IRQ_DIS (i4_irq_disable),
.PULSE_MODE (pulse_mode[1]),
.T_I (t_i[0] ^ aer[4]),
.T_O_PULSE (timera_done)
);
@@ -83,7 +80,6 @@ mfp_timer timer_a (
wire timerb_done;
wire [7:0] timerb_dat_o;
wire [4:0] timerb_ctrl_o;
wire i3_irq_disable;
mfp_timer timer_b (
.CLK (clk),
@@ -95,7 +91,7 @@ mfp_timer timer_b (
.DAT_I (din),
.DAT_O (timerb_dat_o),
.DAT_WE ((addr == 5'h10) && write),
.IRQ_DIS (i3_irq_disable),
.PULSE_MODE (pulse_mode[0]),
.T_I (t_i[1] ^ aer[3]),
.T_O_PULSE (timerb_done)
);
@@ -140,34 +136,27 @@ reg [7:0] aer, ddr, gpip;
reg [15:0] ipr, ier, imr, isr; // interrupt registers
reg [7:0] vr;
// any pending and not masked interrupt causes the irq line to go high
// if highest_irq_pending != higest_irq_active then there's a high prio
// irq in service and no irq is generated until this one is finished
assign irq = ((ipr & imr) != 16'h0000) && (highest_irq_active == highest_irq_pending);
// handle pending and in service irqs
wire [15:0] irq_active_map = (ipr | isr) & imr;
// (i am pretty sure this can be done much more elegant ...)
// check the number of the highest active irq
wire [3:0] highest_irq_active=
( irq_active_map[15] == 1'b1)?4'd15:
((irq_active_map[15:14] == 2'b01)?4'd14:
((irq_active_map[15:13] == 3'b001)?4'd13:
((irq_active_map[15:12] == 4'b0001)?4'd12:
((irq_active_map[15:11] == 5'b00001)?4'd11:
((irq_active_map[15:10] == 6'b000001)?4'd10:
((irq_active_map[15:9] == 7'b0000001)?4'd9:
((irq_active_map[15:8] == 8'b00000001)?4'd8:
((irq_active_map[15:7] == 9'b000000001)?4'd7:
((irq_active_map[15:6] == 10'b000000001)?4'd6:
((irq_active_map[15:5] == 11'b0000000001)?4'd5:
((irq_active_map[15:4] == 12'b00000000001)?4'd4:
((irq_active_map[15:3] == 13'b000000000001)?4'd3:
((irq_active_map[15:2] == 14'b0000000000001)?4'd2:
((irq_active_map[15:1] == 15'b00000000000001)?4'd1:
((irq_active_map[15:0] == 16'b000000000000001)?4'd0:
// generate irq signal if an irq is pending and no other irq of same or higher prio is in service
assign irq = ((ipr & imr) != 16'h0000) && ((isr == 16'h0000) || (highest_irq_pending > irq_in_service));
// check number of current interrupt in service
wire [3:0] irq_in_service =
( isr[15] == 1'b1)?4'd15:
((isr[15:14] == 2'b01)?4'd14:
((isr[15:13] == 3'b001)?4'd13:
((isr[15:12] == 4'b0001)?4'd12:
((isr[15:11] == 5'b00001)?4'd11:
((isr[15:10] == 6'b000001)?4'd10:
((isr[15:9] == 7'b0000001)?4'd9:
((isr[15:8] == 8'b00000001)?4'd8:
((isr[15:7] == 9'b000000001)?4'd7:
((isr[15:6] == 10'b000000001)?4'd6:
((isr[15:5] == 11'b0000000001)?4'd5:
((isr[15:4] == 12'b00000000001)?4'd4:
((isr[15:3] == 13'b000000000001)?4'd3:
((isr[15:2] == 14'b0000000000001)?4'd2:
((isr[15:1] == 15'b00000000000001)?4'd1:
((isr[15:0] == 16'b000000000000001)?4'd0:
4'd0)))))))))))))));
wire [15:0] irq_pending_map = ipr & imr;
@@ -240,7 +229,7 @@ reg [7:0] iD, iD2;
reg [7:0] irq_vec;
// mask of input irqs which are overwritten by timer a/b inputs
wire [7:0] ti_irq_mask = { 3'b000, i4_irq_disable, i3_irq_disable, 3'b000};
wire [7:0] ti_irq_mask = { 3'b000, pulse_mode, 3'b000};
wire [7:0] ti_irq = { 3'b000, t_i[0], t_i[1], 3'b000};
reg iackD;

View File

@@ -13,7 +13,7 @@ module mfp_timer(
inout XCLK_I,
input T_I, // ext. trigger in
output IRQ_DIS, // pulse mode disables input port irq
output PULSE_MODE, // pulse mode disables input port irq
output reg T_O,
output reg T_O_PULSE
@@ -22,7 +22,7 @@ module mfp_timer(
reg [7:0] data, down_counter, cur_counter;
reg [3:0] control;
assign IRQ_DIS = pulse_mode;
assign PULSE_MODE = pulse_mode;
wire[7:0] prescaler; // prescaler value
reg [7:0] prescaler_counter; // prescaler counter
@@ -104,6 +104,11 @@ always @(negedge CLK) begin
if (delay_mode === 1'b1)
if ((~xclk_r2 & xclk_r) === 1'b1)
count <= 1'b1;
// handle pulse mode
if (pulse_mode === 1'b1)
if (((~xclk_r2 & xclk_r) === 1'b1) && T_I)
count <= 1'b1;
if (count) begin

View File

@@ -315,7 +315,7 @@ set_global_assignment -name VHDL_FILE TG68K_ALU.vhd
set_global_assignment -name VHDL_FILE TG68K_Pack.vhd
set_global_assignment -name VHDL_FILE TG68KdotC_Kernel.vhd
set_global_assignment -name SDC_FILE mist.sdc
set_global_assignment -name VHDL_FILE sdram.vhd
set_global_assignment -name VERILOG_FILE sdram.v
set_global_assignment -name VERILOG_FILE clock.v
set_global_assignment -name VERILOG_FILE mist_top.v
set_global_assignment -name VERILOG_FILE user_io.v

View File

@@ -82,16 +82,7 @@ always @(posedge clk_8) begin
end
end
// the following is just to prevent optimization
//assign UART_TX = (berr_cnt_out == 4'd0);
wire cpu_write = cpu_cycle && cpu2io && address_strobe && !tg68_rw;
// it's illegal to write to certain memory areas
// TODO: Still the write itself would succeed. That must not happen
wire cpu_write_illegal = cpu_write &&
(tg68_adr[23:3] === 21'd0); // the first two long words $0 and $4
reg [2:0] dtack_timeout;
always @(posedge clk_8) begin
@@ -102,7 +93,7 @@ always @(posedge clk_8) begin
// timeout only when cpu owns the bus and when
// neither dtack nor fast ram are active
if(dtack_timeout != 3'd7) begin
if(!tg68_dtack || br || tg68_cpuena || tg68_as)
if(!tg68_dtack || br || tg68_as)
dtack_timeout <= 3'd0;
else
dtack_timeout <= dtack_timeout + 3'd1;
@@ -116,7 +107,7 @@ end
// no tristate busses exist inside the FPGA. so bus request doesn't do
// much more than halting the cpu by suppressing dtack
wire br = data_io_br || blitter_br; // && (tg68_cpustate[1:0] == 2'b00) ; // dma is only other bus master (yet)
wire br = data_io_br || blitter_br; // dma/blitter are only other bus masters
wire data_io_br;
// request interrupt ack from mfp for IPL == 6
@@ -251,8 +242,10 @@ wire ste_dma_snd_xsirq, ste_dma_snd_xsirq_delayed;
// mfp io7 is mono_detect which in ste is xor'd with the dma sound irq
wire mfp_io7 = system_ctrl[8] ^ (ste?ste_dma_snd_xsirq:1'b0);
wire [7:0] mfp_gpio_in = {mfp_io7, 1'b0, !dma_irq, !acia_irq, !blitter_irq, 3'b000 };
wire [1:0] mfp_timer_in = {st_de, ste?ste_dma_snd_xsirq_delayed:1'b0};
// input 0 is busy from printer port which has a pullup
// inputs 1,2 and 6 are inputs from serial which have pullups before an inverter
wire [7:0] mfp_gpio_in = {mfp_io7, 1'b0, !dma_irq, !acia_irq, !blitter_irq, 3'b001 };
wire [1:0] mfp_timer_in = {st_de, ste?ste_dma_snd_xsirq_delayed:1'b1};
mfp mfp (
// cpu register interface
@@ -535,20 +528,6 @@ always @ (posedge clk_8) begin
cycle_counter <= cycle_counter + 32'd1;
end
// SDRAM
assign SDRAM_CKE = 1'b1;
assign SDRAM_nCS = sdram_cs[0];
assign SDRAM_DQML = sdram_dqm[0];
assign SDRAM_DQMH = sdram_dqm[1];
wire [ 4-1:0] sdram_cs;
wire [ 2-1:0] sdram_dqm;
// host sdram interface used for io data up/download
wire [2:0] host_state;
wire [22:0] host_addr;
wire [15:0] host_dataWR;
wire [15:0] host_dataRD;
// tg68
wire [ 16-1:0] tg68_dat_in;
@@ -560,16 +539,6 @@ wire tg68_as;
wire tg68_uds;
wire tg68_lds;
wire tg68_rw;
wire tg68_ena7RD;
wire tg68_ena7WR;
wire tg68_enaWR;
wire [ 16-1:0] tg68_cout;
wire tg68_cpuena;
wire [ 32-1:0] tg68_cad;
wire [ 6-1:0] tg68_cpustate /* synthesis noprune */;
wire tg68_cdma;
wire tg68_clds;
wire tg68_cuds;
wire reset = system_ctrl[0];
@@ -625,11 +594,26 @@ always @(posedge clk_8) begin
end
//// TG68K main CPU ////
// tg68 enaXXX signals to make tg68 core happy
reg [3:0] enacnt /* synthesis noprune*/;
wire tg68_ena7RD = (enacnt == 4'd7);
wire tg68_ena7WR = (enacnt == 4'd15);
wire tg68_enaWR = (enacnt[1:0] == 2'd3);
always @(posedge clk_128) begin
// 128Mhz counter synchronous to 8 Mhz clock
// force counter to pass 0 exactly after the rising edge of clk_8
if(((enacnt == 15) && ( clk_8 == 0)) ||
((enacnt == 0) && ( clk_8 == 1)) ||
((enacnt != 15) && (enacnt != 0)))
enacnt <= enacnt + 4'd1;
end
TG68K tg68k (
.clk (clk_128 ),
.reset (~reset ),
.clkena_in (1'b1 ),
.IPL (ipl ), // 3'b111
.IPL (ipl ),
.dtack (tg68_dtack ),
.vpa (1'b1 ),
.ein (1'b1 ),
@@ -642,40 +626,20 @@ TG68K tg68k (
.rw (tg68_rw ),
.berr (tg68_berr ),
.clr_berr (tg68_clr_berr ),
.e ( ),
.vma ( ),
.wrd ( ),
.ena7RDreg (tg68_ena7RD ),
.ena7WRreg (tg68_ena7WR ),
.enaWRreg (tg68_enaWR ),
.fromram (tg68_cout ),
.ramready (tg68_cpuena ),
// odd synchronization signals
.ena7RDreg (tg68_ena7RD ),
.ena7WRreg (tg68_ena7WR ),
.enaWRreg (tg68_enaWR ),
.cpu (system_ctrl[5:4] ), // 00=68000
.ramaddr (tg68_cad ),
.cpustate (tg68_cpustate ),
.nResetOut ( ),
.skipFetch ( ),
.cpuDMA (tg68_cdma ),
.ramlds (tg68_clds ),
.ramuds (tg68_cuds ),
.turbo (system_ctrl[18] )
);
//
wire [15:0] cpu_data_in;
assign cpu_data_in = cpu2mem?ram_data_out:io_data_out;
/* ------------------------------------------------------------------------------ */
/* ----------------------------- memory area mapping ---------------------------- */
/* ------------------------------------------------------------------------------ */
// cpu/video stram multiplexing
wire [22:0] ram_address;
wire [15:0] ram_data_out;
wire video_cycle = (bus_cycle[3:2] == 0);
wire cpu_cycle = (bus_cycle[3:2] == 1); // || (bus_cycle[3:2] == 3);
assign ram_address = video_cycle?((st_hs&&ste)?ste_dma_snd_addr:video_address):
(blitter_br?blitter_master_addr:tg68_adr[23:1]);
// TODO: put 0x000000 to 0x000007 into tos section so it's write protected
wire MEM512K = (system_ctrl[3:1] == 3'd0);
wire MEM1M = (system_ctrl[3:1] == 3'd1);
wire MEM2M = (system_ctrl[3:1] == 3'd2);
@@ -683,23 +647,30 @@ wire MEM4M = (system_ctrl[3:1] == 3'd3);
wire MEM8M = (system_ctrl[3:1] == 3'd4);
wire MEM14M = (system_ctrl[3:1] == 3'd5);
// rom is also at 0x000000 to 0x000007
wire cpu2lowrom = (tg68_adr[23:3] == 21'd0);
// ram from 0x000000 to 0x400000
wire cpu2ram = (tg68_adr[23:22] == 2'b00) || // ordinary 4MB
wire cpu2ram = (!cpu2lowrom) && (
(tg68_adr[23:22] == 2'b00) || // ordinary 4MB
((MEM14M || MEM8M) && (tg68_adr[23:22] == 2'b01)) || // 8MB
(MEM14M && ((tg68_adr[23:22] == 2'b10) || // 12MB
(tg68_adr[23:21] == 3'b110))); // 14MB
(tg68_adr[23:21] == 3'b110)))); // 14MB
wire cpu2ram14 = (tg68_adr[23:22] == 2'b00) || // ordinary 4MB
wire cpu2ram14 = (!cpu2lowrom) && (
(tg68_adr[23:22] == 2'b00) || // ordinary 4MB
(tg68_adr[23:22] == 2'b01) || // 8MB
(tg68_adr[23:22] == 2'b10) || // 12MB
(tg68_adr[23:21] == 3'b110); // 14MB
(tg68_adr[23:21] == 3'b110)); // 14MB
// 256k tos from 0xe00000 to 0xe40000
wire cpu2tos256k = (tg68_adr[23:18] == 6'b111000);
wire cpu2tos256k = (tg68_adr[23:18] == 6'b111000) ||
cpu2lowrom;
// 192k tos from 0xfc0000 to 0xff0000
wire cpu2tos192k = (tg68_adr[23:17] == 7'b1111110) ||
(tg68_adr[23:16] == 8'b11111110);
wire cpu2tos192k = (tg68_adr[23:17] == 7'b1111110) ||
(tg68_adr[23:16] == 8'b11111110) ||
cpu2lowrom;
// 128k cartridge from 0xfa0000 to 0xfc0000
wire cpu2cart = (tg68_adr[23:17] == 7'b1111101);
@@ -717,75 +688,71 @@ wire cpu2iack = (tg68_adr[23:4] == 20'hfffff);
// wire address_strobe = ~tg68_uds || ~tg68_lds;
reg address_strobe;
always @(posedge clk_8)
// address_strobe <= (video_cycle) && (~tg68_lds || ~tg68_uds);
address_strobe <= video_cycle && ~tg68_as && !br;
// generate dtack (for st ram only and rom), TODO: no dtack for rom write
assign tg68_dtack = ~(((cpu2mem && address_strobe) || io_dtack ) && !br);
/* ------------------------------------------------------------------------------ */
/* ------------------------------- bus multiplexer ------------------------------ */
/* ------------------------------------------------------------------------------ */
// Two of the four cycles are being used. One for video (+STE audio) and one for
// cpu, DMA and Blitter
wire video_cycle = (bus_cycle[3:2] == 0);
wire cpu_cycle = (bus_cycle[3:2] == 1);
// ----------------- RAM address --------------
wire [22:0] video_cycle_addr = (st_hs&&ste)?ste_dma_snd_addr:video_address;
wire [22:0] cpu_cycle_addr = data_io_br?data_io_addr:(blitter_br?blitter_master_addr:tg68_adr[23:1]);
wire [22:0] ram_address = video_cycle?video_cycle_addr:cpu_cycle_addr;
// ----------------- RAM read -----------------
// memory access during the video cycle is shared between video and ste_dma_snd
wire video_cycle_oe = (st_hs && ste)?ste_dma_snd_read:video_read;
// memory access during the cpu cycle is shared between blitter and cpu
wire cpu_cycle_oe = (blitter_br?blitter_master_read:(address_strobe && tg68_rw && cpu2mem));
wire cpu_cycle_oe = data_io_br?data_io_read:(blitter_br?blitter_master_read:(address_strobe && tg68_rw && cpu2mem));
wire ram_oe = video_cycle?video_cycle_oe:(cpu_cycle?cpu_cycle_oe:1'b0);
wire ram_oe = ~(video_cycle?video_cycle_oe:(cpu_cycle?cpu_cycle_oe:1'b0));
// (cpu_cycle?~(blitter_br?blitter_master_read:(address_strobe && tg68_rw && cpu2mem)):1'b1);
// (cpu_cycle?~(address_strobe && tg68_rw && cpu2mem):1'b1);
// ----------------- RAM write -----------------
wire video_cycle_wr = 1'b0;
wire cpu_cycle_wr = data_io_br?data_io_write:(blitter_br?blitter_master_write:(address_strobe && ~tg68_rw && cpu2ram));
wire ram_wr = video_cycle?video_cycle_wr:(cpu_cycle?cpu_cycle_wr:1'b0);
wire ram_wr = cpu_cycle?~(blitter_br?blitter_master_write:(address_strobe && ~tg68_rw && cpu2ram)):1'b1;
wire [15:0] ram_data_in = blitter_br?blitter_master_data_out:tg68_dat_out;
wire [15:0] ram_data_out;
wire [15:0] cpu_data_in = cpu2mem?ram_data_out:io_data_out;
wire [15:0] ram_data_in = data_io_br?data_io_dout:(blitter_br?blitter_master_data_out:tg68_dat_out);
// data strobe
wire ram_uds = video_cycle?1'b0:(blitter_br?1'b0:tg68_uds);
wire ram_lds = video_cycle?1'b0:(blitter_br?1'b0:tg68_lds);
wire ram_uds = video_cycle?1'b1:((blitter_br||data_io_br)?1'b1:~tg68_uds);
wire ram_lds = video_cycle?1'b1:((blitter_br||data_io_br)?1'b1:~tg68_lds);
//// sdram ////
assign SDRAM_CKE = 1'b1;
sdram sdram (
.sdata (SDRAM_DQ ),
.sdaddr (SDRAM_A ),
.dqm (sdram_dqm ),
.sd_cs (sdram_cs ),
.ba (SDRAM_BA ),
.sd_we (SDRAM_nWE ),
.sd_ras (SDRAM_nRAS ),
.sd_cas (SDRAM_nCAS ),
.sysclk (clk_128 ),
.reset_in (~init ),
.hostWR (host_dataWR ),
.hostAddr ({host_addr,1'b0} ),
.hostState (host_state ),
.hostL (1'b0 ),
.hostU (1'b0 ),
.hostRD (host_dataRD ),
.hostena ( ),
// interface to the MT48LC16M16 chip
.sd_data ( SDRAM_DQ ),
.sd_addr ( SDRAM_A ),
.sd_dqm ( {SDRAM_DQMH, SDRAM_DQML} ),
.sd_cs ( SDRAM_nCS ),
.sd_ba ( SDRAM_BA ),
.sd_we ( SDRAM_nWE ),
.sd_ras ( SDRAM_nRAS ),
.sd_cas ( SDRAM_nCAS ),
// fast ram interface
.cpuWR (tg68_dat_out ),
.cpuAddr (tg68_cad[24:1] ),
.cpuU (tg68_cuds ),
.cpuL (tg68_clds ),
.cpustate (tg68_cpustate ),
.cpu_dma (tg68_cdma ),
.cpuRD (tg68_cout ),
.cpuena (tg68_cpuena ),
.enaRDreg ( ),
.enaWRreg (tg68_enaWR ),
.ena7RDreg (tg68_ena7RD ),
.ena7WRreg (tg68_ena7WR ),
// system interface
.clk_128 ( clk_128 ),
.clk_8 ( clk_8 ),
.init ( init ),
// chip/slow ram interface
.chipWR (ram_data_in ),
.chipAddr (ram_address ),
.chipU (ram_uds ),
.chipL (ram_lds ),
.chipRW (ram_wr ),
.chip_dma (ram_oe ),
.c_7m (clk_8 ),
.chipRD (ram_data_out ),
.reset_out ( )
// cpu/chipset interface
.din ( ram_data_in ),
.addr ( { 1'b0, ram_address } ),
.ds ( { ram_uds, ram_lds } ),
.we ( ram_wr ),
.oe ( ram_oe ),
.dout ( ram_data_out ),
);
// multiplex spi_do, drive it from user_io if that's selected, drive
@@ -836,10 +803,14 @@ user_io user_io(
.CORE_TYPE(8'ha3) // mist core id
);
wire [22:0] data_io_addr;
wire [15:0] data_io_dout;
wire data_io_write, data_io_read;
data_io data_io (
// system control
.clk_8 (clk_8 ),
.reset (init ),
.reset (init ),
.bus_cycle (bus_cycle[3:2]),
.ctrl_out (system_ctrl ),
@@ -858,10 +829,11 @@ data_io data_io (
.br (data_io_br ),
// ram interface
.state (host_state ),
.addr (host_addr ),
.data_out (host_dataWR ),
.data_in (host_dataRD )
.read (data_io_read ),
.write (data_io_write ),
.addr (data_io_addr ),
.data_out (data_io_dout ),
.data_in (ram_data_out )
);

View File

@@ -1,626 +0,0 @@
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- --
-- Copyright (c) 2009-2011 Tobias Gubener --
-- Subdesign fAMpIGA by TobiFlex --
-- --
-- This source file is free software: you can redistribute it and/or modify --
-- it under the terms of the GNU General Public License as published --
-- by the Free Software Foundation, either version 3 of the License, or --
-- (at your option) any later version. --
-- --
-- This source file 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 General Public License for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-- --
------------------------------------------------------------------------------
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity sdram is
port
(
sdata : inout std_logic_vector(15 downto 0);
sdaddr : out std_logic_vector(12 downto 0);
dqm : out std_logic_vector(1 downto 0);
sd_cs : out std_logic_vector(3 downto 0);
ba : buffer std_logic_vector(1 downto 0);
sd_we : out std_logic;
sd_ras : out std_logic;
sd_cas : out std_logic;
sysclk : in std_logic;
reset_in : in std_logic;
hostWR : in std_logic_vector(15 downto 0);
hostAddr : in std_logic_vector(23 downto 0);
hostState : in std_logic_vector(2 downto 0);
hostL : in std_logic;
hostU : in std_logic;
cpuWR : in std_logic_vector(15 downto 0);
cpuAddr : in std_logic_vector(24 downto 1);
cpuU : in std_logic;
cpuL : in std_logic;
cpustate : in std_logic_vector(5 downto 0);
cpu_dma : in std_logic;
chipWR : in std_logic_vector(15 downto 0);
chipAddr : in std_logic_vector(23 downto 1);
chipU : in std_logic;
chipL : in std_logic;
chipRW : in std_logic;
chip_dma : in std_logic;
c_7m : in std_logic;
hostRD : out std_logic_vector(15 downto 0);
hostena : buffer std_logic;
cpuRD : out std_logic_vector(15 downto 0);
cpuena : out std_logic;
chipRD : out std_logic_vector(15 downto 0);
reset_out : out std_logic;
enaRDreg : out std_logic;
enaWRreg : buffer std_logic;
ena7RDreg : out std_logic;
ena7WRreg : out std_logic
-- c_7m : out std_logic
);
end;
architecture rtl of sdram is
signal initstate :std_logic_vector(3 downto 0);
signal cas_sd_cs :std_logic_vector(3 downto 0);
signal cas_sd_ras :std_logic;
signal cas_sd_cas :std_logic;
signal cas_sd_we :std_logic;
signal cas_dqm :std_logic_vector(1 downto 0);
signal init_done :std_logic;
signal datain :std_logic_vector(15 downto 0);
signal datawr :std_logic_vector(15 downto 0);
signal casaddr :std_logic_vector(24 downto 0);
signal sdwrite :std_logic;
signal sdata_reg :std_logic_vector(15 downto 0);
signal hostCycle :std_logic;
signal zmAddr :std_logic_vector(24 downto 0);
signal zena :std_logic;
signal zcache :std_logic_vector(63 downto 0);
signal zcache_addr :std_logic_vector(23 downto 0);
signal zcache_fill :std_logic;
signal zcachehit :std_logic;
signal zvalid :std_logic_vector(3 downto 0);
signal zequal :std_logic;
signal hostStated :std_logic_vector(1 downto 0);
signal hostRDd :std_logic_vector(15 downto 0);
signal cena :std_logic;
signal ccache :std_logic_vector(63 downto 0);
signal ccache_addr :std_logic_vector(24 downto 0);
signal ccache_fill :std_logic;
signal ccachehit :std_logic;
signal cvalid :std_logic_vector(3 downto 0);
signal cequal :std_logic;
signal cpuStated :std_logic_vector(1 downto 0);
signal cpuRDd :std_logic_vector(15 downto 0);
signal hostSlot_cnt :std_logic_vector(7 downto 0);
signal reset_cnt :std_logic_vector(7 downto 0);
signal reset :std_logic;
signal reset_sdstate :std_logic;
signal c_7md :std_logic;
signal c_7mdd :std_logic;
signal c_7mdr :std_logic;
signal cpuCycle :std_logic;
signal chipCycle :std_logic;
signal slow :std_logic_vector(7 downto 0);
type sdram_states is (ph0,ph1,ph2,ph3,ph4,ph5,ph6,ph7,ph8,ph9,ph10,ph11,ph12,ph13,ph14,ph15);
signal sdram_state : sdram_states;
type pass_states is (nop,ras,cas);
signal pass : pass_states;
begin
process (sysclk, reset_in) begin
if reset_in = '0' THEN
reset_cnt <= "00000000";
reset <= '0';
reset_sdstate <= '0';
elsif (sysclk'event and sysclk='1') THEN
IF reset_cnt="00101010"THEN
reset_sdstate <= '1';
END IF;
IF reset_cnt="10101010"THEN
if sdram_state=ph15 then
reset <= '1';
end if;
ELSE
reset_cnt <= reset_cnt+1;
reset <= '0';
END IF;
end if;
end process;
-------------------------------------------------------------------------
-- SPIHOST cache
-------------------------------------------------------------------------
hostena <= '1' when zena='1' or hostState(1 downto 0)="01" OR zcachehit='1' else '0';
-- TH zmAddr <= '0'& NOT hostAddr(23) & hostAddr(22) & NOT hostAddr(21) & hostAddr(20 downto 0);
zmAddr <= '0'& hostAddr(23 downto 0);
process (sysclk, zmAddr, hostAddr, zcache_addr, zcache, zequal, zvalid, hostRDd)
begin
if zmAddr(23 downto 3)=zcache_addr(23 downto 3) THEN
zequal <='1';
else
zequal <='0';
end if;
zcachehit <= '0';
if zequal='1' and zvalid(0)='1' and hostStated(1)='0' THEN
-- case (hostAddr(2 downto 1)-zcache_addr(2 downto 1)) is
-- when "00"=>
-- zcachehit <= zvalid(0);
-- hostRD <= zcache(63 downto 48);
-- when "01"=>
-- zcachehit <= zvalid(1);
-- hostRD <= zcache(47 downto 32);
-- when "10"=>
-- zcachehit <= zvalid(2);
-- hostRD <= zcache(31 downto 16);
-- when "11"=>
-- zcachehit <= zvalid(3);
-- hostRD <= zcache(15 downto 0);
-- when others=> null;
-- end case;
case (hostAddr(2 downto 1)&zcache_addr(2 downto 1)) is
when "0000"|"0101"|"1010"|"1111"=>
zcachehit <= zvalid(0);
hostRD <= zcache(63 downto 48);
when "0100"|"1001"|"1110"|"0011"=>
zcachehit <= zvalid(1);
hostRD <= zcache(47 downto 32);
when "1000"|"1101"|"0010"|"0111"=>
zcachehit <= zvalid(2);
hostRD <= zcache(31 downto 16);
when "1100"|"0001"|"0110"|"1011"=>
zcachehit <= zvalid(3);
hostRD <= zcache(15 downto 0);
when others=> null;
end case;
else
hostRD <= hostRDd;
end if;
end process;
--Daten<65>bernahme
process (sysclk, reset) begin
if reset = '0' THEN
zcache_fill <= '0';
zena <= '0';
zvalid <= "0000";
elsif (sysclk'event and sysclk='1') THEN
if enaWRreg='1' THEN
zena <= '0';
end if;
if sdram_state=ph9 AND hostCycle='1' THEN
hostRDd <= sdata_reg;
-- if zmAddr=casaddr and cas_sd_cas='0' then
-- zena <= '1';
-- end if;
end if;
if sdram_state=ph11 AND hostCycle='1' THEN
-- hostRDd <= sdata_reg;
if zmAddr=casaddr and cas_sd_cas='0' then
zena <= '1';
end if;
end if;
hostStated <= hostState(1 downto 0);
if zequal='1' and hostState(1 downto 0)="11" THEN
zvalid <= "0000";
end if;
case sdram_state is
when ph7 =>
if hostStated(1)='0' AND hostCycle='1' THEN --only instruction cache
-- if cas_sd_we='1' AND hostStated(1)='0' AND hostCycle='1' THEN --only instruction cache
-- if cas_sd_we='1' AND hostCycle='1' THEN
zcache_addr <= casaddr(23 downto 0);
zcache_fill <= '1';
zvalid <= "0000";
end if;
when ph9 =>
if zcache_fill='1' THEN
zcache(63 downto 48) <= sdata_reg;
-- zvalid(0) <= '1';
end if;
when ph10 =>
if zcache_fill='1' THEN
zcache(47 downto 32) <= sdata_reg;
-- zvalid(1) <= '1';
end if;
when ph11 =>
if zcache_fill='1' THEN
zcache(31 downto 16) <= sdata_reg;
-- zvalid(2) <= '1';
end if;
-- zena <= '0';
when ph12 =>
if zcache_fill='1' THEN
zcache(15 downto 0) <= sdata_reg;
-- zvalid(3) <= '1';
zvalid <= "1111";
end if;
zcache_fill <= '0';
when others => null;
end case;
end if;
end process;
-------------------------------------------------------------------------
-- cpu cache
-------------------------------------------------------------------------
cpuena <= '1' when cena='1' or ccachehit='1' else '0';
process (sysclk, cpuAddr, ccache_addr, ccache, cequal, cvalid, cpuRDd)
begin
if cpuAddr(24 downto 3)=ccache_addr(24 downto 3) THEN
cequal <='1';
else
cequal <='0';
end if;
ccachehit <= '0';
if cequal='1' and cvalid(0)='1' and cpuStated(1)='0' THEN
-- case (cpuAddr(2 downto 1)-ccache_addr(2 downto 1)) is
-- when "00"=>
-- ccachehit <= cvalid(0);
-- cpuRD <= ccache(63 downto 48);
-- when "01"=>
-- ccachehit <= cvalid(1);
-- cpuRD <= ccache(47 downto 32);
-- when "10"=>
-- ccachehit <= cvalid(2);
-- cpuRD <= ccache(31 downto 16);
-- when "11"=>
-- ccachehit <= cvalid(3);
-- cpuRD <= ccache(15 downto 0);
-- when others=> null;
-- end case;
case (cpuAddr(2 downto 1)&ccache_addr(2 downto 1)) is
when "0000"|"0101"|"1010"|"1111"=>
ccachehit <= cvalid(0);
cpuRD <= ccache(63 downto 48);
when "0100"|"1001"|"1110"|"0011"=>
ccachehit <= cvalid(1);
cpuRD <= ccache(47 downto 32);
when "1000"|"1101"|"0010"|"0111"=>
ccachehit <= cvalid(2);
cpuRD <= ccache(31 downto 16);
when "1100"|"0001"|"0110"|"1011"=>
ccachehit <= cvalid(3);
cpuRD <= ccache(15 downto 0);
when others=> null;
end case;
else
cpuRD <= cpuRDd;
end if;
end process;
--Daten<65>bernahme
process (sysclk, reset) begin
if reset = '0' THEN
ccache_fill <= '0';
cena <= '0';
cvalid <= "0000";
elsif (sysclk'event and sysclk='1') THEN
if cpuState(5)='1' THEN
cena <= '0';
end if;
if sdram_state=ph9 AND cpuCycle='1' THEN
cpuRDd <= sdata_reg;
-- if cpuAddr=casaddr(24 downto 1) and cas_sd_cas='0' then
-- cena <= '1';
-- end if;
end if;
if sdram_state=ph11 AND cpuCycle='1' THEN
-- cpuRDd <= sdata_reg;
if cpuAddr=casaddr(24 downto 1) and cas_sd_cas='0' then
cena <= '1';
end if;
end if;
cpuStated <= cpuState(1 downto 0);
if cequal='1' and cpuState(1 downto 0)="11" THEN
cvalid <= "0000";
end if;
case sdram_state is
when ph7 =>
if cpuStated(1)='0' AND cpuCycle='1' THEN --only instruction cache
-- if cas_sd_we='1' AND hostStated(1)='0' AND hostCycle='1' THEN --only instruction cache
-- if cas_sd_we='1' AND hostCycle='1' THEN
ccache_addr <= casaddr;
ccache_fill <= '1';
cvalid <= "0000";
end if;
when ph9 =>
if ccache_fill='1' THEN
ccache(63 downto 48) <= sdata_reg;
-- cvalid(0) <= '1';
end if;
when ph10 =>
if ccache_fill='1' THEN
ccache(47 downto 32) <= sdata_reg;
-- cvalid(1) <= '1';
end if;
when ph11 =>
if ccache_fill='1' THEN
ccache(31 downto 16) <= sdata_reg;
-- cvalid(2) <= '1';
end if;
when ph12 =>
if ccache_fill='1' THEN
ccache(15 downto 0) <= sdata_reg;
-- cvalid(3) <= '1';
cvalid <= "1111";
end if;
ccache_fill <= '0';
when others => null;
end case;
end if;
end process;
-------------------------------------------------------------------------
-- chip cache
-------------------------------------------------------------------------
process (sysclk, sdata_reg)
begin
if (sysclk'event and sysclk='1') THEN
if sdram_state=ph9 AND chipCycle='1' THEN
chipRD <= sdata_reg;
end if;
end if;
end process;
-------------------------------------------------------------------------
-- SDRAM Basic
-------------------------------------------------------------------------
reset_out <= init_done;
process (sysclk, reset, sdwrite, datain) begin
IF sdwrite='1' THEN
sdata <= datawr;
ELSE
sdata <= "ZZZZZZZZZZZZZZZZ";
END IF;
if (sysclk'event and sysclk='0') THEN
c_7md <= c_7m;
END IF;
if (sysclk'event and sysclk='1') THEN
if sdram_state=ph2 THEN
IF chipCycle='1' THEN
datawr <= chipWR;
ELSIF cpuCycle='1' THEN
datawr <= cpuWR;
ELSE
datawr <= hostWR;
END IF;
END IF;
sdata_reg <= sdata;
c_7mdd <= c_7md;
c_7mdr <= c_7md AND NOT c_7mdd;
if reset_sdstate = '0' then
sdwrite <= '0';
enaRDreg <= '0';
enaWRreg <= '0';
ena7RDreg <= '0';
ena7WRreg <= '0';
ELSE
sdwrite <= '0';
enaRDreg <= '0';
enaWRreg <= '0';
ena7RDreg <= '0';
ena7WRreg <= '0';
case sdram_state is --LATENCY=3
when ph2 => sdwrite <= '1';
enaWRreg <= '1';
when ph3 => sdwrite <= '1';
when ph4 => sdwrite <= '1';
when ph5 => sdwrite <= '1';
when ph6 => enaWRreg <= '1';
ena7RDreg <= '1';
-- when ph7 => c_7m <= '0';
when ph10 => enaWRreg <= '1';
when ph14 => enaWRreg <= '1';
ena7WRreg <= '1';
-- when ph15 => c_7m <= '1';
when others => null;
end case;
END IF;
if reset = '0' then
initstate <= (others => '0');
init_done <= '0';
ELSE
case sdram_state is --LATENCY=3
when ph15 => if initstate /= "1111" THEN
initstate <= initstate+1;
else
init_done <='1';
end if;
when others => null;
end case;
END IF;
IF c_7mdr='1' THEN
sdram_state <= ph2;
-- if reset_sdstate = '0' then
-- sdram_state <= ph0;
ELSE
case sdram_state is --LATENCY=3
when ph0 => sdram_state <= ph1;
when ph1 => sdram_state <= ph2;
-- when ph1 =>
-- IF c_28md='1' THEN
-- sdram_state <= ph2;
-- ELSE
-- sdram_state <= ph1;
-- END IF;
when ph2 => sdram_state <= ph3;
-- when ph2 => --sdram_state <= ph3;
-- IF c_28md='0' THEN
-- sdram_state <= ph3;
-- ELSE
-- sdram_state <= ph2;
-- END IF;
when ph3 => sdram_state <= ph4;
when ph4 => sdram_state <= ph5;
when ph5 => sdram_state <= ph6;
when ph6 => sdram_state <= ph7;
when ph7 => sdram_state <= ph8;
when ph8 => sdram_state <= ph9;
when ph9 => sdram_state <= ph10;
when ph10 => sdram_state <= ph11;
when ph11 => sdram_state <= ph12;
when ph12 => sdram_state <= ph13;
when ph13 => sdram_state <= ph14;
when ph14 => sdram_state <= ph15;
-- when ph15 => sdram_state <= ph0;
when others => sdram_state <= ph0;
end case;
END IF;
END IF;
end process;
process (sysclk, initstate, pass, hostAddr, datain, init_done, casaddr, cpuU, cpuL, hostCycle) begin
if (sysclk'event and sysclk='1') THEN
sd_cs <="1111";
sd_ras <= '1';
sd_cas <= '1';
sd_we <= '1';
sdaddr <= "XXXXXXXXXXXXX";
ba <= "00";
dqm <= "00";
if init_done='0' then
if sdram_state =ph1 then
case initstate is
when "0010" => --PRECHARGE
sdaddr(10) <= '1'; --all banks
sd_cs <="0000";
sd_ras <= '0';
sd_cas <= '1';
sd_we <= '0';
when "0011"|"0100"|"0101"|"0110"|"0111"|"1000"|"1001"|"1010"|"1011"|"1100" => --AUTOREFRESH
sd_cs <="0000";
sd_ras <= '0';
sd_cas <= '0';
sd_we <= '1';
when "1101" => --LOAD MODE REGISTER
sd_cs <="0000";
sd_ras <= '0';
sd_cas <= '0';
sd_we <= '0';
-- ba <= "00";
-- sdaddr <= "0001000100010"; --BURST=4 LATENCY=2
sdaddr <= "0001000110010"; --BURST=4 LATENCY=3
when others => null; --NOP
end case;
END IF;
else
-- Time slot control
if sdram_state=ph1 THEN
cpuCycle <= '0';
chipCycle <= '0';
hostCycle <= '0';
cas_sd_cs <= "1110";
cas_sd_ras <= '1';
cas_sd_cas <= '1';
cas_sd_we <= '1';
IF slow(2 downto 0)=5 THEN
slow <= slow+3;
ELSE
slow <= slow+1;
END IF;
-- IF dma='0' OR cpu_dma='0' THEN
IF hostSlot_cnt /= "00000000" THEN
hostSlot_cnt <= hostSlot_cnt-1;
END IF;
-- IF chip_dma='1' THEN
IF chip_dma='0' OR chipRW='0' THEN
chipCycle <= '1';
sdaddr <= '0'&chipAddr(20 downto 9);
-- ba <= "00";
ba <= chipAddr(22 downto 21);
-- cas_dqm <= "00"; --only word access
cas_dqm <= chipU& chipL;
sd_cs <= "1110"; --ACTIVE
sd_ras <= '0';
casaddr <= '0'&chipAddr&'0';
datain <= chipWR;
cas_sd_cas <= '0';
cas_sd_we <= chipRW;
-- ELSIF cpu_dma='1' AND hostSlot_cnt /= "00000000" THEN
-- ELSIF cpu_dma='0' OR cpuRW='0' THEN
ELSIF cpuState(2)='0' AND cpuState(5)='0' THEN
cpuCycle <= '1';
sdaddr <= cpuAddr(24)&cpuAddr(20 downto 9);
ba <= cpuAddr(22 downto 21);
cas_dqm <= cpuU& cpuL;
sd_cs <= "1110"; --ACTIVE
sd_ras <= '0';
casaddr <= cpuAddr(24 downto 1)&'0';
datain <= cpuWR;
cas_sd_cas <= '0';
cas_sd_we <= NOT cpuState(1) OR NOT cpuState(0);
ELSE
hostSlot_cnt <= "00001111";
-- ELSIF hostState(2)='1' OR hostena='1' OR slow(3 downto 0)="0001" THEN --refresh cycle
IF hostState(2)='1' OR hostena='1' THEN --refresh cycle
-- ELSIF slow(3 downto 0)="0001" THEN --refresh cycle
sd_cs <="0000"; --AUTOREFRESH
sd_ras <= '0';
sd_cas <= '0';
ELSE
hostCycle <= '1';
sdaddr <= '0'&zmAddr(20 downto 9);
ba <= zmAddr(22 downto 21);
cas_dqm <= hostU& hostL;
sd_cs <= "1110"; --ACTIVE
sd_ras <= '0';
casaddr <= zmAddr;
datain <= hostWR;
cas_sd_cas <= '0';
IF hostState="011" THEN
cas_sd_we <= '0';
-- dqm <= hostU& hostL;
END IF;
END IF;
END IF;
END IF;
if sdram_state=ph4 then
sdaddr <= '0'&'0' & '1' & '0' & casaddr(23)&casaddr(8 downto 1);--auto precharge
ba <= casaddr(22 downto 21);
sd_cs <= cas_sd_cs;
IF cas_sd_we='0' THEN
dqm <= cas_dqm;
END IF;
sd_ras <= cas_sd_ras;
sd_cas <= cas_sd_cas;
sd_we <= cas_sd_we;
END IF;
END IF;
END IF;
END process;
END;

View File

@@ -247,7 +247,6 @@ always @(negedge reg_clk) begin
// disable STE hard scroll features
line_offset <= 8'h00;
pixel_offset <= 4'h0;
// pixel_offset <= 4'h1; // XXX
if(DEFAULT_MODE == 0) begin
// TOS default palette, can be disabled after tests