Added basic ROM and fiddled things

Clock now runs at 6MHz while I try to simplify things to figure out a
CPU bug
This commit is contained in:
Alan Garfield 2018-01-10 16:39:18 +11:00
parent ae1d371e37
commit 158510c299
10 changed files with 4171 additions and 111 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*_Implmnt
*.xcf
*.log
synlog.tcl

View File

@ -4,7 +4,7 @@ Version=Lattice Semiconductor Corporation iCEcube - Release: 2017.08.27940 - Bui
ProjectName=apple1
Vendor=SiliconBlue
Synthesis=synplify
ProjectVFiles=MUX.v=work,basic.v=work,chip_6502.v=work,clk_div.v=work,uart.v=work,flag.v=work,tm1638.v=work,led_and_key.v
ProjectVFiles=basic.v=work,uart.v=work,tm1638.v=work,led_and_key.v=work,chip_6502.v,MUX.v
ProjectCFiles=
CurImplementation=apple1_Implmnt
Implementations=apple1_Implmnt
@ -16,11 +16,11 @@ DeviceFamily=iCE40
Device=HX8K
DevicePackage=CT256
DevicePower=
NetlistFile=apple1_Implmnt/apple1.edf
NetlistFile=
AdditionalEDIFFile=
IPEDIFFile=
DesignLib=apple1_Implmnt/sbt/netlist/oadb-top
DesignView=_rt
DesignView=
DesignCell=top
SynthesisSDCFile=apple1_Implmnt/apple1.scf
UserPinConstraintFile=

View File

@ -1,7 +1,7 @@
#-- Synopsys, Inc.
#-- Version L-2016.09L+ice40
#-- Project file C:\Users\Alan\Desktop\projects\apple1\apple1_syn.prd
#-- Written on Mon Jan 01 01:15:55 2018
#-- Written on Thu Jan 04 21:48:56 2018
#
### Watch Implementation type ###

View File

@ -8,14 +8,12 @@
add_file -verilog -lib work "MUX.v"
add_file -verilog -lib work "basic.v"
add_file -verilog -lib work "chip_6502.v"
add_file -verilog -lib work "clk_div.v"
add_file -verilog -lib work "uart.v"
add_file -verilog -lib work "flag.v"
add_file -verilog -lib work "tm1638.v"
add_file -verilog -lib work "led_and_key.v"
add_file -verilog -lib work "chip_6502.v"
add_file -verilog -lib work "MUX.v"
#implementation: "apple1_Implmnt"
impl -add apple1_Implmnt -type fpga

4096
basic.hex Normal file

File diff suppressed because it is too large Load Diff

95
basic.v
View File

@ -1,33 +1,43 @@
`define LED_KEYS
module top(
input clk12,
input clk,
input uart_rx,
output uart_tx,
output uart_cts,
`ifdef LED_KEYS
output tm_cs,
output tm_clk,
inout tm_dio,
`endif
output reg [7:0] led
);
wire res, rw, irq, nmi;
wire [15:0] ab;
wire [7:0] dbo;
reg [7:0] dbi;
//////////////////////////////////////////////////////////////////////////
// CLK DIVIDER
/*
wire clk;
clk_div u_clk_div(
.clk (clk12),
.clk_out (clk)
);
*/
//////////////////////////////////////////////////////////////////////////
// 6502 reset
reg [7:0] start;
always @(posedge clk)
if (~start[7]) start <= start + 1;
if (~start[7]) start <= start + 1;
assign res = start[7];
//////////////////////////////////////////////////////////////////////////
@ -37,25 +47,18 @@ module top(
always @(posedge clk)
div <= div + 1;
assign phi0 = div[3];
wire clk_phi;
SB_GB bg_phi (
.USER_SIGNAL_TO_GLOBAL_BUFFER(phi0),
.USER_SIGNAL_TO_GLOBAL_BUFFER(div[3]),
.GLOBAL_BUFFER_OUTPUT(clk_phi)
);
//////////////////////////////////////////////////////////////////////////
// 6502
wire rw, res, irq, nmi, phi0;
wire [15:0] ab;
wire [7:0] dbo;
reg [7:0] dbi;
chip_6502 chip_6502 (
.clk (clk),
.phi (phi0),
.phi (clk_phi),
.res (res),
.so (1'b0),
.rdy (1'b1),
@ -72,16 +75,16 @@ module top(
// USB UART
wire received, is_receiving, rx_error, is_transmitting, transmit;
reg [7:0] tx_byte;
reg [6:0] tx_byte;
wire [7:0] rx_byte;
uart #(.CLOCK_DIVIDE( 625 )) my_uart (
clk12, // master clock for this component
clk, // master clock for this component
~res, // synchronous reset line (resets if high)
uart_rx, // receive data on this line
uart_tx, // transmit data on this line
transmit, // signal to indicate that the UART should start a transmission
tx_byte, // 8-bit bus with byte to be transmitted when transmit is raised high
{1'b0, tx_byte}, // 8-bit bus with byte to be transmitted when transmit is raised high
received, // output flag raised high for one cycle of clk when a byte is received
rx_byte, // byte which has just been received when received is raise
is_receiving, // indicates that we are currently receiving data on the rx lin
@ -89,21 +92,24 @@ module top(
rx_error // rx packet corrupt
);
// sync the TX latch to the clk12 domain
// sync the TX latch to the clk domain
reg apple_tx;
/*
Flag_CrossDomain tx_flag (
.clkA(clk_phi),
.FlagIn_clkA(apple_tx),
.clkB(clk12),
.clkB(clk),
.FlagOut_clkB(transmit)
);
*/
assign transmit = apple_tx;
// sync the RX flag, using flag and ack
reg [6:0] apple_rx_buf;
reg apple_rx_ack;
reg apple_rx_flag;
always @(posedge clk12)
always @(posedge clk)
begin
if (received && !apple_rx_flag && !apple_rx_ack) begin
apple_rx_flag <= 1;
@ -120,13 +126,14 @@ module top(
//////////////////////////////////////////////////////////////////////////
// TM1638 Display
`ifdef LED_KEYS
reg [3:0] display;
reg [7:0] digits[7:0];
reg [7:0] leds;
wire [7:0] keys;
ledAndKey my_led_and_keys (
.clk (clk12),
.clk (clk_phi),
.rst (~res),
.display (display),
.digit1 (digits[0]),
@ -143,6 +150,7 @@ module top(
.tm_clk (tm_clk),
.tm_dio (tm_dio)
);
`endif
//////////////////////////////////////////////////////////////////////////
// I/O locations
@ -153,25 +161,20 @@ module top(
localparam LED_KEYS = 16'hD020; // Start address of the Led&Keys module
localparam LED = 16'hD000; // Breakout board LEDs
/*
0x77 - A
0X73 - P
0X73 - P
0X38 - L
0X79 - E
0X40 - -
0X06 - 1
*/
//////////////////////////////////////////////////////////////////////////
// RAM and ROM
reg [7:0] ram[0:8191];
reg [7:0] ram[0:8191] /* synthesis syn_ramstyle = "block_ram" */;
reg [7:0] basic[0:4091] /* synthesis syn_ramstyle = "block_ram" */;
reg [7:0] rom[0:255] /* synthesis syn_ramstyle = "block_ram" */;
initial begin
$readmemh("../ram.hex", ram, 0, 8191);
$readmemh("../rom.hex", ram, 8192-256, 8191);
$readmemh("../ram.hex", ram, 0, 8191);
$readmemh("../rom.hex", rom, 0, 255);
$readmemh("../basic.hex", basic, 0, 4091);
end
//always @(posedge clk_phi)
always @(posedge clk_phi)
begin
// clear the UART RX ack if set
@ -194,7 +197,7 @@ module top(
begin
// Apple 1 terminal only uses 7 bits, MSB indicates
// terminal has ack'd RX
tx_byte <= {1'b0, dbo[6:0]};
tx_byte <= dbo[6:0];
apple_tx <= 1;
end
end
@ -218,6 +221,7 @@ module top(
end
end
`ifdef LED_KEYS
// LED&KEYS registers
LED_KEYS: if (rw) dbi <= {4'b0, display}; else display <= dbo[3:0];
LED_KEYS + 1: if (rw) dbi <= digits[0]; else digits[0] <= dbo;
@ -230,23 +234,28 @@ module top(
LED_KEYS + 8: if (rw) dbi <= digits[7]; else digits[7] <= dbo;
LED_KEYS + 9: if (rw) dbi <= leds; else leds <= dbo;
LED_KEYS + 10: if (rw) dbi <= keys;
`endif
// breakout board LED registers
LED: if (rw) dbi <= led; else led <= dbo;
default:
begin
// RAM 0x0000 -> 0x1FFF, ROM 0xFF00 -> 0xFFFF
//
// !!!! ROM also at 0x1F00 -> 0x1FFF but writeable!!!!
//
// All other addresses return zero.
//
if (ab[15:13] == 3'b0 || ab[15:8] == 8'b11111111)
if (ab[15:12] == 4'b0000 || ab[15:12] == 4'b0001)
begin
// handle RAM/ROM address
// 0x0000 -> 0x1FFF - RAM
dbi <= ram[ab[12:0]];
if (~rw && ~ab[15]) ram[ab[12:0]] <= dbo;
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

View File

@ -1,32 +0,0 @@
module clk_div
#(
//parameter WIDTH = 16,
//parameter N = 65535 // divide by 12
parameter WIDTH = 4,
parameter N = 1 // divide by 12
)
(
input clk,
output clk_out
);
reg [WIDTH-1:0] r_reg;
wire [WIDTH-1:0] r_nxt;
reg clk_track;
always @(posedge clk)
begin
if (r_nxt == N)
begin
r_reg <= 0;
clk_track <= ~clk_track;
end
else
r_reg <= r_nxt;
end
assign r_nxt = r_reg + 1;
assign clk_out = clk_track;
endmodule

15
flag.v
View File

@ -1,15 +0,0 @@
module Flag_CrossDomain(
input clkA,
input FlagIn_clkA, // this is a one-clock pulse from the clkA domain
input clkB,
output FlagOut_clkB // from which we generate a one-clock pulse in clkB domain
);
reg FlagToggle_clkA;
always @(posedge clkA) FlagToggle_clkA <= FlagToggle_clkA ^ FlagIn_clkA; // when flag is asserted, this signal toggles (clkA domain)
reg [2:0] SyncA_clkB;
always @(posedge clkB) SyncA_clkB <= {SyncA_clkB[1:0], FlagToggle_clkA}; // now we cross the clock domains
assign FlagOut_clkB = (SyncA_clkB[2] ^ SyncA_clkB[1]); // and create the clkB flag
endmodule

View File

@ -1,13 +1,13 @@
# For the iCE40HX-8K Breakout Board
## System Clock
set_io clk12 J3
set_io clk J3
### UART (FTDI Channel B)
set_io uart_rx B10
set_io uart_tx B12
set_io uart_cts A15
set_io uart_rts B13
#set_io uart_rts B13
### TM1638 Display
set_io tm_clk P1
@ -24,14 +24,14 @@ set_io led[2] C4
set_io led[1] B3
set_io led[0] C3
set_io ledx[7] J1
set_io ledx[6] J2
set_io ledx[5] K1
set_io ledx[4] K3
set_io ledx[3] L1
set_io ledx[2] L3
set_io ledx[1] M1
set_io ledx[0] M2
#set_io ledx[7] J1
#set_io ledx[6] J2
#set_io ledx[5] K1
#set_io ledx[4] K3
#set_io ledx[3] L1
#set_io ledx[2] L3
#set_io ledx[1] M1
#set_io ledx[0] M2
#set_io d[0] B1
#set_io d[1] B2

View File

@ -10,7 +10,7 @@ module tm1638(
output sclk,
input dio_in,
output dio_out
output reg dio_out
);
localparam CLK_DIV = 3; // seems happy at 12MHz with 3
@ -23,7 +23,7 @@ module tm1638(
reg [1:0] cur_state, next_state;
reg [CLK_DIV1:0] sclk_d, sclk_q;
reg [7:0] data_d, data_q, data_out_d, data_out_q;
reg dio_out, dio_out_d;
reg dio_out_d;
reg [2:0] ctr_d, ctr_q;
// output read data if we're reading
@ -115,4 +115,4 @@ module tm1638(
data_out_q <= data_out_d;
end
end
endmodule
endmodule