Merge branch 'sdram'
This commit is contained in:
+143
-50
@@ -17,57 +17,73 @@ module spectrum(output wire[7:0] LED,
|
||||
output wire VGA_HS,
|
||||
output wire VGA_VS,
|
||||
input wire[3:0] SW, // 0 = ROM selection, 1 = enable/disable interrupts, 2 = turbo speed
|
||||
output wire[33:0] GPIO_1, // Exports CPU chip pins,
|
||||
output wire[31:0] GPIO_1, // Exports CPU chip pins,
|
||||
output wire buzzer_out,
|
||||
input wire raw_loader_in
|
||||
input wire raw_loader_in,
|
||||
output wire[1:0] DRAM_BA,
|
||||
output wire[1:0] DRAM_DQM,
|
||||
output wire DRAM_RAS_N,
|
||||
output wire DRAM_CAS_N,
|
||||
output wire DRAM_CKE,
|
||||
output wire DRAM_CLK,
|
||||
output wire DRAM_WE_N,
|
||||
output wire DRAM_CS_N,
|
||||
inout wire[15:0] DRAM_DQ,
|
||||
output wire[12:0] DRAM_ADDR,
|
||||
// output wire[2:0] GPIO_0,
|
||||
//-------- Atari joystick mapped as Kempston
|
||||
input wire [4:0] kempston, // Input with weak pull-up
|
||||
output wire kempston_gnd, // Helps mapping to DB9 cable
|
||||
input wire turbo_button,
|
||||
input wire kempston_autofire_button
|
||||
|
||||
);
|
||||
`default_nettype none
|
||||
|
||||
/*
|
||||
assign GPIO_1[0] = VGA_VS;
|
||||
assign GPIO_1[1] = VGA_HS;
|
||||
assign GPIO_1[2] = VGA_B[0];
|
||||
assign GPIO_1[3] = vs_nintr;
|
||||
|
||||
wire clk_pix; // VGA pixel clock (25.175 MHz)
|
||||
wire locked;
|
||||
wire clk_vram;
|
||||
|
||||
pll_video pll_(
|
||||
.locked(locked),
|
||||
.inclk0(CLOCK_50),
|
||||
.c0(clk_pix)
|
||||
);
|
||||
|
||||
|
||||
reg [12:0] vram_address;
|
||||
reg [7:0] vram_data;
|
||||
rom_scr rom_(
|
||||
.clock(CLOCK_50),
|
||||
.address(vram_address),
|
||||
.q(vram_data)
|
||||
// .q(8'b10111000)
|
||||
);
|
||||
|
||||
wire [2:0] border; // Border color index value
|
||||
assign border = SW[2:0];
|
||||
|
||||
wire vs_nintr; // Vertical retrace interrupt
|
||||
video video_( .*, .vram_address(vram_address), .vram_data(vram_data) );
|
||||
//video video_( .*, .vram_address(vram_address), .vram_data(8'b10111000) );
|
||||
*/
|
||||
|
||||
|
||||
|
||||
wire reset;
|
||||
wire locked;
|
||||
assign reset = locked & KEY[0:0];
|
||||
|
||||
reg turbo = 0;
|
||||
wire turbo_button_debounced;
|
||||
debouncer debounce_turbo(
|
||||
.i_Clk(CLOCK_50),
|
||||
.i_Switch(turbo_button),
|
||||
.o_Switch(turbo_button_debounced)
|
||||
);
|
||||
|
||||
always @(negedge turbo_button_debounced)
|
||||
begin
|
||||
turbo = !turbo;
|
||||
end
|
||||
|
||||
|
||||
reg kempston_autofire_enabled = 0;
|
||||
wire kempston_autofire_button_debounced;
|
||||
debouncer debounce_autofire(
|
||||
.i_Clk(CLOCK_50),
|
||||
.i_Switch(kempston_autofire_button),
|
||||
.o_Switch(kempston_autofire_button_debounced)
|
||||
);
|
||||
always @(negedge kempston_autofire_button_debounced)
|
||||
begin
|
||||
kempston_autofire_enabled = !kempston_autofire_enabled;
|
||||
end
|
||||
|
||||
|
||||
// Export selected pins to the extension connector
|
||||
assign GPIO_1[15:0] = A[15:0];
|
||||
assign GPIO_1[23:16] = D[7:0];
|
||||
assign GPIO_1[31:24] = {nM1,nMREQ,nIORQ,nRD,nWR,nRFSH,nHALT,nBUSACK};
|
||||
assign kempston_gnd = 0; // enable kempston
|
||||
|
||||
assign LED[7] = !kempston[4] & kempston_auto_fire;
|
||||
assign LED[6] = !kempston[3];
|
||||
assign LED[5] = !kempston[2];
|
||||
assign LED[4] = !kempston[1];
|
||||
assign LED[3] = !kempston[0];
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Internal buses and address map selection logic
|
||||
@@ -80,7 +96,7 @@ wire RamWE;
|
||||
assign RamWE = A[15:14]==2'b01 && nIORQ==1 && nRD==1 && nWR==0;
|
||||
|
||||
wire ExtRamWE; // Extended (and external) 32K RAM
|
||||
assign ExtRamWE = A[15]==1 && nIORQ==1 && nRD==1 && nWR==0;
|
||||
assign ExtRamWE = A[15]==1'b1 && nIORQ==1 && nRD==1 && nWR==0;
|
||||
|
||||
wire [7:0] ula_data; // ULA
|
||||
wire io_we;
|
||||
@@ -91,6 +107,43 @@ assign io_we = nIORQ==0 && nRD==1 && nWR==0;
|
||||
// 0000 - 3FFF 16K ROM (mapped to rom0)
|
||||
// 4000 - 7FFF 16K dual-port ram0
|
||||
// 8000 - FFFF 32K RAM (mapped to ram1)
|
||||
|
||||
|
||||
|
||||
|
||||
wire is_io_read_requested;
|
||||
wire is_io_write_requested;
|
||||
wire is_mem_read_requested;
|
||||
wire is_mem_write_requested;
|
||||
wire is_rom_address;
|
||||
wire is_upper_ram_address;
|
||||
|
||||
assign is_rom_address = A[15:14] == 2'b00;
|
||||
assign is_upper_ram_address = A[15] == 1'b1;
|
||||
assign is_io_read_requested = {nIORQ,nRD,nWR} == 3'b001 ? 1'b1 : 1'b0;
|
||||
assign is_io_write_requested = {nIORQ,nRD,nWR} == 3'b010 ? 1'b1 : 1'b0;
|
||||
assign is_mem_read_requested = {nIORQ,nRD,nWR} == 3'b101 ? 1'b1 : 1'b0;
|
||||
assign is_mem_write_requested = {nIORQ,nRD,nWR} == 3'b110 ? 1'b1 : 1'b0;
|
||||
|
||||
// assign D = sdram_out_valid ? sdram_out_data[7:0] : 8b'zzzzzzzz;
|
||||
|
||||
//assign D = is_io_read_requested ? ula_data : (is_mem_read_requested ? (A[15:14] == 2'b00 ? rom_data : (sdram_out_valid ? sdram_out_data : {8{1'bz}})) : {8{1'bz}});
|
||||
|
||||
reg kempston_auto_fire = 0;
|
||||
reg kempston_last_fire_state = 0;
|
||||
reg[17:0] kempston_auto_fire_counter = 0;
|
||||
|
||||
always @(posedge clk_cpu)
|
||||
begin
|
||||
if (kempston_autofire_enabled == 0)
|
||||
kempston_auto_fire <= 1;
|
||||
else begin
|
||||
kempston_auto_fire_counter <= kempston_auto_fire_counter + 1;
|
||||
if (kempston_auto_fire_counter == 0)
|
||||
kempston_auto_fire <= !kempston_auto_fire;
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) // always_comb
|
||||
begin
|
||||
case ({nIORQ,nRD,nWR})
|
||||
@@ -99,30 +152,28 @@ begin
|
||||
|
||||
// Memory read --------------------------------
|
||||
3'b101: begin
|
||||
casez (A[15:14])
|
||||
2'b00: D[7:0] = rom_data;
|
||||
2'b01: D[7:0] = ram0_data;
|
||||
casez (A[15:14])
|
||||
2'b00: D[7:0] = rom_data;
|
||||
2'b01: D[7:0] = ram0_data;
|
||||
2'b1?: D[7:0] = ram1_data;
|
||||
endcase
|
||||
endcase
|
||||
end
|
||||
// ---------------------------------- IO read ----------------------------------
|
||||
3'b001: begin
|
||||
// Normally data supplied by the ULA
|
||||
D[7:0] = ula_data;
|
||||
/*
|
||||
|
||||
// Kempston joystick at the IO address 0x1F; active bits are high:
|
||||
// FIRE UP DOWN LEFT RIGHT
|
||||
if (A[7:0]==8'h1F) begin
|
||||
D[7:0] = { 3'b0, !kempston[4],!kempston[0],!kempston[1],!kempston[2],!kempston[3] };
|
||||
D[7:0] = { 3'b0, !kempston[4] & kempston_auto_fire,!kempston[0],!kempston[1],!kempston[2],!kempston[3] };
|
||||
end
|
||||
*/
|
||||
end
|
||||
default:
|
||||
D[7:0] = {8{1'bz}};
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Instantiate ROM, 16K
|
||||
// ----------------------------------------------------
|
||||
@@ -168,12 +219,53 @@ ram32 ram1(
|
||||
.wren(ExtRamWE)
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// SDRAM for 128K
|
||||
//
|
||||
|
||||
wire[23:0] sdram_address;
|
||||
wire[31:0] sdram_out_data;
|
||||
wire[31:0] sdram_in_data;
|
||||
wire sdram_read_request;
|
||||
wire sdram_write_request;
|
||||
wire sdram_out_valid;
|
||||
|
||||
assign sdram_write_request = is_upper_ram_address && is_mem_write_requested;
|
||||
assign sdram_read_request = is_upper_ram_address && is_mem_read_requested;
|
||||
assign sdram_in_data = {24'd0, D[7:0]};
|
||||
assign sdram_address = {8'd0, A[15:0]};
|
||||
|
||||
sdram_controller sdram_(
|
||||
.CLOCK_50(CLOCK_50),
|
||||
.DRAM_ADDR(DRAM_ADDR),
|
||||
.DRAM_BA(DRAM_BA),
|
||||
.DRAM_CAS_N(DRAM_CAS_N),
|
||||
.DRAM_CKE(DRAM_CKE),
|
||||
.DRAM_CLK(DRAM_CLK),
|
||||
.DRAM_CS_N(DRAM_CS_N),
|
||||
.DRAM_DQ(DRAM_DQ),
|
||||
.DRAM_DQM(DRAM_DQM),
|
||||
.DRAM_RAS_N(DRAM_RAS_N),
|
||||
.DRAM_WE_N(DRAM_WE_N),
|
||||
|
||||
.address(sdram_address),
|
||||
.req_read(sdram_read_request),
|
||||
.req_write(ExtRamWE),
|
||||
.data_out(sdram_out_data),
|
||||
.data_out_valid(sdram_out_valid),
|
||||
.data_in(sdram_in_data)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Instantiate ULA
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
wire clk_cpu; // Global CPU clock of 3.5 MHz
|
||||
assign LED[2:2] = SW[2:2]; // Glow red when in turbo mode (7.0 MHz)
|
||||
assign LED[3:3] = raw_loader_in; // feedback from audio in
|
||||
assign LED[2] = turbo; // Glow red when in turbo mode (7.0 MHz)
|
||||
assign LED[1] = raw_loader_in; // feedback from audio in
|
||||
wire [12:0] vram_address; // ULA video block requests a byte from the video RAM
|
||||
wire [7:0] vram_data; // ULA video block reads a byte from the video RAM
|
||||
wire vs_nintr; // Generates a vertical retrace interrupt
|
||||
@@ -183,7 +275,7 @@ wire beeper; // Show the beeper state
|
||||
ula ula_(
|
||||
//-------- Clocks and reset -----------------
|
||||
.CLOCK_50 (CLOCK_50), // Input clock 50 MHz
|
||||
.turbo (SW[2:2]), // Turbo speed (3.5 MHz x 2 = 7.0 MHz)
|
||||
.turbo (turbo), // Turbo speed (3.5 MHz x 2 = 7.0 MHz)
|
||||
.clk_vram (clk_vram),
|
||||
.nreset (reset), // KEY0 is reset; on DE1, keys are active low!
|
||||
.locked (locked), // PLL is locked signal
|
||||
@@ -206,7 +298,7 @@ ula ula_(
|
||||
.PS2_DAT (PS2_DAT),
|
||||
.pressed (pressed),
|
||||
|
||||
//-------- Audio (Tape player) --------------
|
||||
//-------- Audio (e player) --------------
|
||||
.I2C_SCLK (I2C_SCLK),
|
||||
.I2C_SDAT (I2C_SDAT),
|
||||
.AUD_XCK (AUD_XCK),
|
||||
@@ -225,6 +317,7 @@ ula ula_(
|
||||
.VGA_B (VGA_B),
|
||||
.VGA_HS (VGA_HS),
|
||||
.VGA_VS (VGA_VS)
|
||||
|
||||
);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Reference in New Issue
Block a user