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:
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
);
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user