verilog-apple-one/rtl/apple1_top.v
2018-01-27 00:21:05 +11:00

189 lines
4.6 KiB
Verilog

`define ICE40
module top(
input clk,
input uart_rx,
output uart_tx,
output uart_cts,
output [7:0] led,
output [7:0] ledx
);
//////////////////////////////////////////////////////////////////////////
// Registers and Wires
reg [15:0] ab;
wire [7:0] dbi;
reg [7:0] dbo;
reg we;
//////////////////////////////////////////////////////////////////////////
// Clocks
wire clk25;
wire cpu_clken;
`ifdef ICE40
clocks my_clocks(
.clk(clk),
.clk25(clk25),
.cpu_clken(cpu_clken)
);
`endif
//////////////////////////////////////////////////////////////////////////
// Reset
wire reset;
reg hard_reset;
reg [5:0] reset_cnt;
wire pwr_up_reset = &reset_cnt;
always @(posedge clk25)
begin
if (cpu_clken)
begin
if (!pwr_up_reset)
reset_cnt <= reset_cnt + 1;
hard_reset <= pwr_up_reset;
end
end
assign reset = ~hard_reset;
//////////////////////////////////////////////////////////////////////////
// 6502
wire [7:0] dbo_c;
wire [15:0] ab_c;
wire we_c;
reg [7:0] dbi_c;
cpu my_cpu (
.clk (clk25),
.reset (reset),
.AB (ab_c),
.DI (dbi_c),
.DO (dbo_c),
.WE (we_c),
.IRQ (1'b0),
.NMI (1'b0),
.RDY (cpu_clken)
);
always @(posedge clk25)
begin
if (cpu_clken)
begin
ab <= ab_c;
dbo <= dbo_c;
dbi_c <= dbi;
we <= we_c;
end
end
//////////////////////////////////////////////////////////////////////////
// RAM and ROM
wire ram_cs = (ab[15:13] == 3'b000); // 0x0000 -> 0x1FFF
wire uart_cs = (ab[15:2] == 14'b11010000000100); // 0xD010 -> 0xD013
wire basic_cs = (ab[15:12] == 4'b1110); // 0xE000 -> 0xEFFF
wire rom_cs = (ab[15:8] == 8'b11111111); // 0xFF00 -> 0xFFFF
// RAM
wire [7:0] ram_dout;
ram my_ram (
.clk(clk25),
.address(ab[12:0]),
.w_en(we & ram_cs),
.din(dbo),
.dout(ram_dout)
);
// WozMon ROM
wire [7:0] rom_dout;
rom_wozmon my_rom_wozmon (
.clk(clk25),
.address(ab[7:0]),
.dout(rom_dout)
);
// UART
wire [7:0] uart_dout;
uart my_uart (
.clk(clk25),
.uart_rx(uart_rx),
.uart_tx(uart_tx),
.uart_cts(uart_cts),
.enable(uart_cs & cpu_clken),
.address(ab[1:0]),
.w_en(we & uart_cs),
.din(dbo),
.dout(uart_dout),
.led(led)
);
// link up chip selected device to cpu input
assign dbi = ram_cs ? ram_dout :
rom_cs ? rom_dout :
uart_cs ? uart_dout :
8'hFF;
assign ledx = ab[7:0];
// always @(posedge clk25)
// begin
// if (cpu_clken)
// begin
// led <= ab[7:0];
// ledx <= ~ab[15:8];
// end
// end
// reg [7:0] ram[0:8191] /* synthesis syn_ramstyle = "block_ram" */;
// reg [7:0] rom[0:255] /* synthesis syn_ramstyle = "block_ram" */;
// reg [7:0] basic[0:4095] /* synthesis syn_ramstyle = "block_ram" */;
//
// initial begin
// $readmemh("../roms/ram.hex", ram, 0, 8191);
// $readmemh("../roms/rom.hex", rom, 0, 255);
// $readmemh("../roms/basic.hex", basic, 0, 4095);
// end
//
// always @(posedge clk_25)
// begin
// if (phi_clk_en)
// begin
// if (res)
// begin
// case(ab)
// default:
// begin
// if (ab[15:12] == 4'b0000 || ab[15:12] == 4'b0001)
// begin
// // 0x0000 -> 0x1FFF - RAM
// dbi <= ram[ab[12:0]];
// if (~rw) ram[ab[12:0]] <= dbo;
// end
// else if (ab[15:12] == 4'b1110)
// begin
// // 0xE000 -> 0xEFFF - BASIC
// dbi <= basic[ab[11:0]];
// end
// else if (ab[15:8] == 8'b11111111)
// begin
// // 0xFF00 -> 0xFFFF - ROM
// dbi <= rom[ab[7:0]];
// end
// else
// // unknown address return zero
// dbi <= 8'h0;
// end
//
// endcase
// end
// end
// end
endmodule