Merge branch '23-create-a-better-simulation-environment' into 'master'
Resolve "Create a better simulation environment" Closes #23 See merge request bslathi19/super6502!23
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
||||
[submodule "sw/cc65"]
|
||||
path = sw/cc65
|
||||
url = https://git.byronlathi.com/bslathi19/cc65
|
||||
[submodule "hw/efinix_fpga/simulation/src/verilog-6502"]
|
||||
path = hw/efinix_fpga/simulation/src/verilog-6502
|
||||
url = https://git.byronlathi.com/bslathi19/verilog-6502
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
TARGETS= timer interrupt_controller spi_controller
|
||||
TB=$(patsubst %, %_tb.sv, $(TARGETS))
|
||||
SRCS=$(shell find src/ -type f -name "*.*v")
|
||||
SRCS+=$(shell find ../ip/ -type f -name "*.*v" -not \( -name "*tmpl*" \))
|
||||
SRCS+=$(shell find ../src/ -type f -name "*.*v")
|
||||
|
||||
all: $(TARGETS)
|
||||
INC=$(shell find include/ -type f)
|
||||
|
||||
timer: timer_tb.sv
|
||||
iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv
|
||||
TEST_PROGRAM_NAME?=loop_test
|
||||
|
||||
spi_controller: spi_controller_tb.sv ../spi_controller.sv
|
||||
iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv
|
||||
TEST_PROGRAM?=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME)/$(TEST_PROGRAM_NAME).hex
|
||||
|
||||
interrupt_controller: interrupt_controller_tb.sv
|
||||
iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv
|
||||
#TODO implement something like sources.list
|
||||
|
||||
TOP_MODULE=sim_top
|
||||
TARGET=sim_top
|
||||
INIT_MEM=init_hex.mem
|
||||
FLAGS=-DSIM -DRTL_SIM
|
||||
|
||||
all: $(INIT_MEM)
|
||||
iverilog -g2005-sv $(FLAGS) -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS)
|
||||
|
||||
$(INIT_MEM):
|
||||
cp $(TEST_PROGRAM) ./init_hex.mem
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS)
|
||||
rm -f *.vcd
|
||||
rm -f *.vvp
|
||||
rm -rf $(TARGET)
|
||||
rm -rf $(INIT_MEM)
|
||||
@@ -0,0 +1,80 @@
|
||||
// =============================================================================
|
||||
// Generated by efx_ipmgr
|
||||
// Version: 2023.1.150
|
||||
// IP Version: 5.0
|
||||
// =============================================================================
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2013-2023 Efinix Inc. All rights reserved.
|
||||
//
|
||||
// This document contains proprietary information which is
|
||||
// protected by copyright. All rights are reserved. This notice
|
||||
// refers to original work by Efinix, Inc. which may be derivitive
|
||||
// of other work distributed under license of the authors. In the
|
||||
// case of derivative work, nothing in this notice overrides the
|
||||
// original author's license agreement. Where applicable, the
|
||||
// original license agreement is included in it's original
|
||||
// unmodified form immediately below this header.
|
||||
//
|
||||
// WARRANTY DISCLAIMER.
|
||||
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
||||
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
||||
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
||||
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
||||
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
||||
//
|
||||
// LIMITATION OF LIABILITY.
|
||||
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
||||
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
||||
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
||||
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
||||
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
||||
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
||||
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
||||
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
||||
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
||||
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
||||
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
||||
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
||||
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
||||
// APPLY TO LICENSEE.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
localparam fSYS_MHz = 100;
|
||||
localparam fCK_MHz = 200;
|
||||
localparam tIORT_u = 2;
|
||||
localparam CL = 3;
|
||||
localparam BL = 1;
|
||||
localparam DDIO_TYPE = "SOFT";
|
||||
localparam DQ_WIDTH = 8;
|
||||
localparam DQ_GROUP = 2;
|
||||
localparam BA_WIDTH = 2;
|
||||
localparam ROW_WIDTH = 13;
|
||||
localparam COL_WIDTH = 9;
|
||||
localparam tPWRUP = 200000;
|
||||
localparam tRAS = 44;
|
||||
localparam tRAS_MAX = 120000;
|
||||
localparam tRC = 66;
|
||||
localparam tRCD = 20;
|
||||
localparam tREF = 64000000;
|
||||
localparam tRFC = 66;
|
||||
localparam tRP = 20;
|
||||
localparam tWR = 2;
|
||||
localparam tMRD = 2;
|
||||
localparam SDRAM_MODE = "Native";
|
||||
localparam DATA_RATE = 2;
|
||||
localparam AXI_AWADDR_WIDTH = 24;
|
||||
localparam AXI_WDATA_WIDTH = 32;
|
||||
localparam AXI_ARADDR_WIDTH = 24;
|
||||
localparam AXI_RDATA_WIDTH = 32;
|
||||
localparam AXI_AWID_WIDTH = 4;
|
||||
localparam AXI_AWUSER_WIDTH = 2;
|
||||
localparam AXI_WUSER_WIDTH = 2;
|
||||
localparam AXI_BID_WIDTH = 4;
|
||||
localparam AXI_BUSER_WIDTH = 2;
|
||||
localparam AXI_ARID_WIDTH = 4;
|
||||
localparam AXI_ARUSER_WIDTH = 3;
|
||||
localparam AXI_RUSER_WIDTH = 3;
|
||||
@@ -1,76 +0,0 @@
|
||||
module sim();
|
||||
|
||||
timeunit 10ns;
|
||||
timeprecision 1ns;
|
||||
|
||||
logic clk;
|
||||
logic reset;
|
||||
logic [2:0] addr;
|
||||
logic [7:0] i_data;
|
||||
logic [7:0] o_data;
|
||||
logic cs;
|
||||
logic rwb;
|
||||
|
||||
logic irqb_master;
|
||||
logic irqb0, irqb1, irqb2, irqb3, irqb4, irqb5, irqb6, irqb7;
|
||||
|
||||
interrupt_controller dut(
|
||||
.*);
|
||||
|
||||
always #100 clk = clk === 1'b0;
|
||||
|
||||
task write_reg(input logic [2:0] _addr, input logic [7:0] _data);
|
||||
@(negedge clk);
|
||||
cs <= '1;
|
||||
addr <= _addr;
|
||||
rwb <= '0;
|
||||
i_data <= '1;
|
||||
@(posedge clk);
|
||||
i_data <= _data;
|
||||
@(negedge clk);
|
||||
cs <= '0;
|
||||
rwb <= '1;
|
||||
endtask
|
||||
|
||||
task read_reg(input logic [2:0] _addr, output logic [7:0] _data);
|
||||
@(negedge clk);
|
||||
cs <= '1;
|
||||
addr <= _addr;
|
||||
rwb <= '1;
|
||||
i_data <= '1;
|
||||
@(posedge clk);
|
||||
_data <= o_data;
|
||||
@(negedge clk);
|
||||
cs <= '0;
|
||||
rwb <= '1;
|
||||
endtask
|
||||
|
||||
initial
|
||||
begin
|
||||
$dumpfile("interrupt_controller.vcd");
|
||||
$dumpvars(0,sim);
|
||||
end
|
||||
|
||||
initial begin
|
||||
reset <= '1;
|
||||
irqb0 <= '1;
|
||||
irqb1 <= '1;
|
||||
irqb2 <= '1;
|
||||
irqb3 <= '1;
|
||||
irqb4 <= '1;
|
||||
irqb5 <= '1;
|
||||
irqb6 <= '1;
|
||||
irqb7 <= '1;
|
||||
repeat(5) @(posedge clk);
|
||||
reset <= '0;
|
||||
|
||||
repeat(5) @(posedge clk);
|
||||
|
||||
irqb0 <= '0;
|
||||
|
||||
repeat(5) @(posedge clk);
|
||||
|
||||
$finish();
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -1,102 +0,0 @@
|
||||
module sim();
|
||||
|
||||
timeunit 10ns;
|
||||
timeprecision 1ns;
|
||||
|
||||
logic clk_50;
|
||||
|
||||
logic i_clk;
|
||||
logic i_rst;
|
||||
|
||||
logic i_cs;
|
||||
logic i_rwb;
|
||||
logic [1:0] i_addr;
|
||||
logic [7:0] i_data;
|
||||
logic [7:0] o_data;
|
||||
|
||||
logic o_spi_cs;
|
||||
logic o_spi_clk;
|
||||
logic o_spi_mosi;
|
||||
logic i_spi_miso;
|
||||
|
||||
spi_controller dut(.*);
|
||||
|
||||
always #1 clk_50 = clk_50 === 1'b0;
|
||||
always #100 i_clk = i_clk === 1'b0;
|
||||
|
||||
task write_reg(input logic [2:0] _addr, input logic [7:0] _data);
|
||||
@(negedge i_clk);
|
||||
i_cs <= '1;
|
||||
i_addr <= _addr;
|
||||
i_rwb <= '0;
|
||||
i_data <= '1;
|
||||
@(posedge i_clk);
|
||||
i_data <= _data;
|
||||
@(negedge i_clk);
|
||||
i_cs <= '0;
|
||||
i_rwb <= '1;
|
||||
endtask
|
||||
|
||||
task read_reg(input logic [2:0] _addr, output logic [7:0] _data);
|
||||
@(negedge i_clk);
|
||||
i_cs <= '1;
|
||||
i_addr <= _addr;
|
||||
i_rwb <= '1;
|
||||
i_data <= '1;
|
||||
@(posedge i_clk);
|
||||
_data <= o_data;
|
||||
@(negedge i_clk);
|
||||
i_cs <= '0;
|
||||
i_rwb <= '1;
|
||||
endtask
|
||||
|
||||
initial
|
||||
begin
|
||||
$dumpfile("spi_controller.vcd");
|
||||
$dumpvars(0,sim);
|
||||
end
|
||||
|
||||
logic [7:0] data;
|
||||
|
||||
initial begin
|
||||
i_rst <= '1;
|
||||
repeat(5) @(posedge i_clk);
|
||||
i_cs <= '0;
|
||||
i_rwb <= '1;
|
||||
i_addr <= '0;
|
||||
i_rst <= '0;
|
||||
|
||||
repeat(5) @(posedge i_clk);
|
||||
|
||||
write_reg(3, 1);
|
||||
write_reg(2, 8'hFF);
|
||||
data = (1 << 7);
|
||||
while(data & (1 << 7)) begin
|
||||
read_reg(3, data);
|
||||
end
|
||||
write_reg(3, 0);
|
||||
read_reg(1, data);
|
||||
assert(data == 8'h55);
|
||||
|
||||
repeat(50) @(posedge i_clk);
|
||||
|
||||
$finish();
|
||||
end
|
||||
|
||||
|
||||
logic [7:0] _spi_device_data;
|
||||
|
||||
initial begin
|
||||
_spi_device_data <= 8'h55;
|
||||
end
|
||||
|
||||
always @(edge o_spi_clk) begin
|
||||
if (o_spi_cs == '0) begin
|
||||
if (o_spi_clk == '1)
|
||||
i_spi_miso <= _spi_device_data[7];
|
||||
if (o_spi_clk == '0)
|
||||
_spi_device_data <= _spi_device_data << 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
1145
hw/efinix_fpga/simulation/src/generic_sdr.v
Normal file
1145
hw/efinix_fpga/simulation/src/generic_sdr.v
Normal file
File diff suppressed because it is too large
Load Diff
154
hw/efinix_fpga/simulation/src/sim_top.sv
Normal file
154
hw/efinix_fpga/simulation/src/sim_top.sv
Normal file
@@ -0,0 +1,154 @@
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module sim_top();
|
||||
|
||||
`include "include/super6502_sdram_controller_define.vh"
|
||||
|
||||
logic r_sysclk, r_sdrclk, r_clk_50, r_clk_2;
|
||||
|
||||
// clk_100
|
||||
initial begin
|
||||
r_sysclk <= '1;
|
||||
forever begin
|
||||
#5 r_sysclk <= ~r_sysclk;
|
||||
end
|
||||
end
|
||||
|
||||
// clk_200
|
||||
initial begin
|
||||
r_sdrclk <= '1;
|
||||
forever begin
|
||||
#2.5 r_sdrclk <= ~r_sdrclk;
|
||||
end
|
||||
end
|
||||
|
||||
// clk_50
|
||||
initial begin
|
||||
r_clk_50 <= '1;
|
||||
forever begin
|
||||
#10 r_clk_50 <= ~r_clk_50;
|
||||
end
|
||||
end
|
||||
|
||||
// clk_2
|
||||
initial begin
|
||||
r_clk_2 <= '1;
|
||||
forever begin
|
||||
#250 r_clk_2 <= ~r_clk_2;
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("sim_top.vcd");
|
||||
$dumpvars(0,sim_top);
|
||||
end
|
||||
|
||||
logic button_reset;
|
||||
|
||||
initial begin
|
||||
button_reset <= '0;
|
||||
repeat(10) @(r_clk_2);
|
||||
button_reset <= '1;
|
||||
repeat(20000) @(r_clk_2);
|
||||
$finish();
|
||||
end
|
||||
|
||||
logic w_cpu_reset;
|
||||
logic [15:0] w_cpu_addr;
|
||||
logic [7:0] w_cpu_data_from_cpu, w_cpu_data_from_dut;
|
||||
logic w_cpu_rdy;
|
||||
logic w_cpu_we;
|
||||
logic w_cpu_phi2;
|
||||
|
||||
//TODO: this
|
||||
cpu_65c02 u_cpu(
|
||||
.phi2(w_cpu_phi2),
|
||||
.reset(~w_cpu_reset),
|
||||
.AB(w_cpu_addr),
|
||||
.RDY(w_cpu_rdy),
|
||||
.IRQ('0),
|
||||
.NMI('0),
|
||||
.DI_s1(w_cpu_data_from_dut),
|
||||
.DO(w_cpu_data_from_cpu),
|
||||
.WE(w_cpu_we)
|
||||
);
|
||||
|
||||
|
||||
// Having the super6502 causes an infinite loop,
|
||||
// but just the rom works. Need to whittle down
|
||||
// which block is causing it.
|
||||
// rom #(.DATA_WIDTH(8), .ADDR_WIDTH(12)) u_rom(
|
||||
// .addr(w_cpu_addr[11:0]),
|
||||
// .clk(r_clk_2),
|
||||
// .data(w_cpu_data_from_dut)
|
||||
// );
|
||||
|
||||
//TODO: also this
|
||||
super6502 u_dut(
|
||||
.i_sysclk(r_sysclk),
|
||||
.i_sdrclk(r_sdrclk),
|
||||
.i_tACclk(~r_sdrclk),
|
||||
.clk_50(r_clk_50),
|
||||
.clk_2(r_clk_2),
|
||||
.button_reset(button_reset),
|
||||
.cpu_resb(w_cpu_reset),
|
||||
.cpu_addr(w_cpu_addr),
|
||||
.cpu_data_out(w_cpu_data_from_dut),
|
||||
.cpu_data_in(w_cpu_data_from_cpu),
|
||||
.cpu_rwb(~w_cpu_we),
|
||||
.cpu_rdy(w_cpu_rdy),
|
||||
.cpu_phi2(w_cpu_phi2),
|
||||
|
||||
.o_sdr_CKE(w_sdr_CKE),
|
||||
.o_sdr_n_CS(w_sdr_n_CS),
|
||||
.o_sdr_n_WE(w_sdr_n_WE),
|
||||
.o_sdr_n_RAS(w_sdr_n_RAS),
|
||||
.o_sdr_n_CAS(w_sdr_n_CAS),
|
||||
.o_sdr_BA(w_sdr_BA),
|
||||
.o_sdr_ADDR(w_sdr_ADDR),
|
||||
.i_sdr_DATA(w_sdr_DQ),
|
||||
.o_sdr_DATA(w_sdr_DATA),
|
||||
.o_sdr_DATA_oe(w_sdr_DATA_oe),
|
||||
.o_sdr_DQM(w_sdr_DQM)
|
||||
);
|
||||
|
||||
wire w_sdr_CKE;
|
||||
wire w_sdr_n_CS;
|
||||
wire w_sdr_n_WE;
|
||||
wire w_sdr_n_RAS;
|
||||
wire w_sdr_n_CAS;
|
||||
wire [BA_WIDTH -1:0]w_sdr_BA;
|
||||
wire [ROW_WIDTH -1:0]w_sdr_ADDR;
|
||||
wire [DQ_GROUP *DQ_WIDTH -1:0]w_sdr_DATA;
|
||||
wire [DQ_GROUP *DQ_WIDTH -1:0]w_sdr_DATA_oe;
|
||||
wire [DQ_GROUP -1:0]w_sdr_DQM;
|
||||
wire [DQ_GROUP *DQ_WIDTH -1:0]w_sdr_DQ;
|
||||
|
||||
genvar i, j;
|
||||
generate
|
||||
for (i=0; i<DQ_GROUP*DQ_WIDTH; i=i+1)
|
||||
begin: DQ_map
|
||||
assign w_sdr_DQ[i] = (w_sdr_DATA_oe[i])?
|
||||
w_sdr_DATA[i]:1'bz;
|
||||
end
|
||||
|
||||
for (j=0; j<DQ_GROUP; j=j+1)
|
||||
begin : mem_inst
|
||||
generic_sdr inst_sdr
|
||||
(
|
||||
.Dq(w_sdr_DQ[((j+1)*(DQ_WIDTH))-1:((j)*DQ_WIDTH)]),
|
||||
.Addr(w_sdr_ADDR[ROW_WIDTH-1:0]),
|
||||
.Ba(w_sdr_BA[BA_WIDTH-1:0]),
|
||||
.Clk(~r_sdrclk),
|
||||
.Cke(w_sdr_CKE),
|
||||
.Cs_n(w_sdr_n_CS),
|
||||
.Ras_n(w_sdr_n_RAS),
|
||||
.Cas_n(w_sdr_n_CAS),
|
||||
.We_n(w_sdr_n_WE),
|
||||
.Dqm(w_sdr_DQM[j])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
endmodule
|
||||
1
hw/efinix_fpga/simulation/src/verilog-6502
Submodule
1
hw/efinix_fpga/simulation/src/verilog-6502
Submodule
Submodule hw/efinix_fpga/simulation/src/verilog-6502 added at aaf4c084ef
@@ -1,75 +0,0 @@
|
||||
module sim();
|
||||
|
||||
timeunit 10ns;
|
||||
timeprecision 1ns;
|
||||
|
||||
logic clk;
|
||||
logic rwb;
|
||||
logic clk_50;
|
||||
logic reset;
|
||||
|
||||
logic [2:0] addr;
|
||||
logic [7:0] i_data;
|
||||
logic [7:0] o_data;
|
||||
logic cs;
|
||||
logic irq;
|
||||
|
||||
timer dut(
|
||||
.*);
|
||||
|
||||
always #1 clk_50 = clk_50 === 1'b0;
|
||||
always #100 clk = clk === 1'b0;
|
||||
|
||||
task write_reg(input logic [2:0] _addr, input logic [7:0] _data);
|
||||
@(negedge clk);
|
||||
cs <= '1;
|
||||
addr <= _addr;
|
||||
rwb <= '0;
|
||||
i_data <= '1;
|
||||
@(posedge clk);
|
||||
i_data <= _data;
|
||||
@(negedge clk);
|
||||
cs <= '0;
|
||||
rwb <= '1;
|
||||
endtask
|
||||
|
||||
task read_reg(input logic [2:0] _addr, output logic [7:0] _data);
|
||||
@(negedge clk);
|
||||
cs <= '1;
|
||||
addr <= _addr;
|
||||
rwb <= '1;
|
||||
i_data <= '1;
|
||||
@(posedge clk);
|
||||
_data <= o_data;
|
||||
@(negedge clk);
|
||||
cs <= '0;
|
||||
rwb <= '1;
|
||||
endtask
|
||||
|
||||
initial
|
||||
begin
|
||||
$dumpfile("timer.vcd");
|
||||
$dumpvars(0,sim);
|
||||
end
|
||||
|
||||
logic [7:0] read_data;
|
||||
|
||||
initial begin
|
||||
reset <= '1;
|
||||
repeat(5) @(posedge clk);
|
||||
reset <= '0;
|
||||
|
||||
write_reg(5, 16);
|
||||
|
||||
repeat(1024) @(posedge clk);
|
||||
|
||||
repeat(10) begin
|
||||
read_reg(0, read_data);
|
||||
$display("Read: %d", read_data);
|
||||
repeat(1024) @(posedge clk);
|
||||
end
|
||||
$finish();
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -1,17 +1,21 @@
|
||||
module addr_decode
|
||||
(
|
||||
input [15:0] i_addr,
|
||||
input logic [15:0] i_addr,
|
||||
|
||||
output o_rom_cs,
|
||||
output o_leds_cs,
|
||||
output o_timer_cs,
|
||||
output o_multiplier_cs,
|
||||
output o_divider_cs,
|
||||
output o_uart_cs,
|
||||
output o_spi_cs,
|
||||
output o_sdram_cs
|
||||
output logic o_rom_cs,
|
||||
output logic o_leds_cs,
|
||||
output logic o_timer_cs,
|
||||
output logic o_multiplier_cs,
|
||||
output logic o_divider_cs,
|
||||
output logic o_uart_cs,
|
||||
output logic o_spi_cs,
|
||||
output logic o_sdram_cs
|
||||
);
|
||||
|
||||
// assign o_rom_cs = '1;
|
||||
always_comb begin
|
||||
o_rom_cs = (i_addr >= 16'hf000) ? 1 : 0;
|
||||
end
|
||||
assign o_rom_cs = i_addr >= 16'hf000 && i_addr <= 16'hffff;
|
||||
assign o_timer_cs = i_addr >= 16'heff8 && i_addr <= 16'heffb;
|
||||
assign o_multiplier_cs = i_addr >= 16'heff0 && i_addr <= 16'heff7;
|
||||
|
||||
@@ -104,7 +104,7 @@ end
|
||||
|
||||
logic r_wait;
|
||||
logic _r_wait;
|
||||
assign o_wait = r_wait;
|
||||
assign o_wait = r_wait & i_cs;
|
||||
|
||||
// we need to assert rdy low until a falling edge if a reset happens
|
||||
|
||||
@@ -245,10 +245,11 @@ logic [3:0] o_dbg_BA;
|
||||
logic [25:0] o_dbg_ADDR;
|
||||
logic [31:0] o_dbg_DATA_out;
|
||||
logic [31:0] o_dbg_DATA_in;
|
||||
logic o_sdr_init_done;
|
||||
logic sdr_init_done;
|
||||
logic [3:0] o_sdr_state;
|
||||
|
||||
assign o_ref_req = o_dbg_ref_req;
|
||||
assign o_sdr_init_done = sdr_init_done;
|
||||
|
||||
|
||||
sdram_controller u_sdram_controller(
|
||||
@@ -265,7 +266,7 @@ sdram_controller u_sdram_controller(
|
||||
.i_din(r_write_data), //Data to write to SDRAM. Twice normal width when running at half speed (hence the even addresses)
|
||||
.i_dm(r_dm), //dm (r_dm)
|
||||
.o_dout(w_data_o), //Data read from SDRAM, doubled as above.
|
||||
.o_sdr_init_done(o_sdr_init_done), //Indicates that the SDRAM initialization is done.
|
||||
.o_sdr_init_done(sdr_init_done), //Indicates that the SDRAM initialization is done.
|
||||
.o_wr_ack(w_wr_ack), //Write acknowledge, handshake with we
|
||||
.o_rd_ack(w_rd_ack), //Read acknowledge, handshake with re
|
||||
.o_rd_valid(w_rd_valid),//Read valid. The data on o_dout is valid
|
||||
|
||||
@@ -90,6 +90,7 @@ always_comb begin
|
||||
1: o_data = r_input_data;
|
||||
2:;
|
||||
3: o_data = {active, r_control[6:0]};
|
||||
default: o_data = 'x;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
@@ -81,17 +81,6 @@ logic w_divider_cs;
|
||||
logic w_uart_cs;
|
||||
logic w_spi_cs;
|
||||
|
||||
addr_decode u_addr_decode(
|
||||
.i_addr(cpu_addr),
|
||||
.o_rom_cs(w_rom_cs),
|
||||
.o_leds_cs(w_leds_cs),
|
||||
.o_timer_cs(w_timer_cs),
|
||||
.o_multiplier_cs(w_multiplier_cs),
|
||||
.o_divider_cs(w_divider_cs),
|
||||
.o_uart_cs(w_uart_cs),
|
||||
.o_spi_cs(w_spi_cs),
|
||||
.o_sdram_cs(w_sdram_cs)
|
||||
);
|
||||
|
||||
logic [7:0] w_rom_data_out;
|
||||
logic [7:0] w_leds_data_out;
|
||||
@@ -103,6 +92,16 @@ logic [7:0] w_spi_data_out;
|
||||
logic [7:0] w_sdram_data_out;
|
||||
|
||||
always_comb begin
|
||||
w_rom_cs = cpu_addr >= 16'hf000 && cpu_addr <= 16'hffff;
|
||||
w_timer_cs = cpu_addr >= 16'heff8 && cpu_addr <= 16'heffb;
|
||||
w_multiplier_cs = cpu_addr >= 16'heff0 && cpu_addr <= 16'heff7;
|
||||
w_divider_cs = cpu_addr >= 16'hefe8 && cpu_addr <= 16'hefef;
|
||||
w_uart_cs = cpu_addr >= 16'hefe6 && cpu_addr <= 16'hefe7;
|
||||
w_spi_cs = cpu_addr >= 16'hefd8 && cpu_addr <= 16'hefdb;
|
||||
w_leds_cs = cpu_addr == 16'hefff;
|
||||
w_sdram_cs = cpu_addr < 16'he000;
|
||||
|
||||
|
||||
if (w_rom_cs)
|
||||
cpu_data_out = w_rom_data_out;
|
||||
else if (w_leds_cs)
|
||||
|
||||
@@ -123,6 +123,8 @@ always_comb begin
|
||||
o_data = status;
|
||||
end
|
||||
|
||||
default: o_data = 'x;
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
@@ -46,8 +46,9 @@ enum bit [1:0] {READY, WAIT, TRANSMIT} state, next_state;
|
||||
|
||||
always_ff @(posedge clk_50) begin
|
||||
if (reset) begin
|
||||
state = READY;
|
||||
state <= READY;
|
||||
irqb <= '1;
|
||||
status <= '0;
|
||||
end else begin
|
||||
state <= next_state;
|
||||
end
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
# export PATH=$PATH:"$EFXPT_HOME/bin"
|
||||
|
||||
source $EFX_SETUP
|
||||
export REPO_TOP=$(git rev-parse --show-toplevel)
|
||||
|
||||
|
||||
# python -m venv .user_venv --system-site-packages
|
||||
# . .user_venv/bin/activate
|
||||
@@ -7,7 +7,7 @@ NAME=bios
|
||||
BIN=$(NAME).bin
|
||||
HEX=$(NAME).hex
|
||||
|
||||
FPGA_IMG=../../hw/efinix_fpga/init_hex.mem
|
||||
FPGA_IMG=$(REPO_TOP)/hw/efinix_fpga/init_hex.mem
|
||||
EFX_RUN=/home/byron/Software/efinity/2023.1/scripts/efx_run.py
|
||||
EFX_PRJ=/home/byron/Projects/super6502/hw/efinix_fpga/super6502.xml
|
||||
|
||||
|
||||
39
sw/test_code/loop_test/Makefile
Normal file
39
sw/test_code/loop_test/Makefile
Normal file
@@ -0,0 +1,39 @@
|
||||
CC=../../cc65/bin/cl65
|
||||
LD=../../cc65/bin/cl65
|
||||
CFLAGS=-T -t none -I. --cpu "65C02"
|
||||
LDFLAGS=-C link.ld -m $(NAME).map
|
||||
|
||||
NAME=loop_test
|
||||
|
||||
BIN=$(NAME).bin
|
||||
HEX=$(NAME).hex
|
||||
|
||||
LISTS=lists
|
||||
|
||||
SRCS=$(wildcard *.s) $(wildcard *.c)
|
||||
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
|
||||
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
|
||||
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
|
||||
|
||||
# Make sure the kernel linked to correct address, no relocation!
|
||||
all: $(HEX)
|
||||
|
||||
$(HEX): $(BIN)
|
||||
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
|
||||
|
||||
%.o: %.c $(LISTS)
|
||||
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
|
||||
|
||||
%.o: %.s $(LISTS)
|
||||
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
|
||||
|
||||
$(LISTS):
|
||||
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map
|
||||
|
||||
35
sw/test_code/loop_test/link.ld
Normal file
35
sw/test_code/loop_test/link.ld
Normal file
@@ -0,0 +1,35 @@
|
||||
MEMORY
|
||||
{
|
||||
ZP: start = $0, size = $100, type = rw, define = yes;
|
||||
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
|
||||
ROM: start = $F000, size = $1000, file = %O;
|
||||
}
|
||||
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp, define = yes;
|
||||
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
|
||||
BSS: load = SDRAM, type = bss, define = yes;
|
||||
HEAP: load = SDRAM, type = bss, optional = yes;
|
||||
STARTUP: load = ROM, type = ro;
|
||||
ONCE: load = ROM, type = ro, optional = yes;
|
||||
CODE: load = ROM, type = ro;
|
||||
RODATA: load = ROM, type = ro;
|
||||
VECTORS: load = ROM, type = ro, start = $FFFA;
|
||||
}
|
||||
|
||||
FEATURES {
|
||||
CONDES: segment = STARTUP,
|
||||
type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__;
|
||||
CONDES: segment = STARTUP,
|
||||
type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__;
|
||||
}
|
||||
|
||||
SYMBOLS {
|
||||
# Define the stack size for the application
|
||||
__STACKSIZE__: value = $0200, type = weak;
|
||||
__STACKSTART__: type = weak, value = $0800; # 2k stack
|
||||
}
|
||||
16
sw/test_code/loop_test/main.s
Normal file
16
sw/test_code/loop_test/main.s
Normal file
@@ -0,0 +1,16 @@
|
||||
.export _init, _nmi_int, _irq_int
|
||||
|
||||
.code
|
||||
|
||||
_nmi_int:
|
||||
_irq_int:
|
||||
|
||||
_init:
|
||||
lda #$00
|
||||
@1: inc
|
||||
sta $01
|
||||
lda $01
|
||||
cmp $01
|
||||
beq @1
|
||||
|
||||
@end: bra @end
|
||||
14
sw/test_code/loop_test/vectors.s
Normal file
14
sw/test_code/loop_test/vectors.s
Normal file
@@ -0,0 +1,14 @@
|
||||
; ---------------------------------------------------------------------------
|
||||
; vectors.s
|
||||
; ---------------------------------------------------------------------------
|
||||
;
|
||||
; Defines the interrupt vector table.
|
||||
|
||||
.import _init
|
||||
.import _nmi_int, _irq_int
|
||||
|
||||
.segment "VECTORS"
|
||||
|
||||
.addr _nmi_int ; NMI vector
|
||||
.addr _init ; Reset vector
|
||||
.addr _irq_int ; IRQ/BRK vector
|
||||
39
sw/test_code/simple_mem_test/Makefile
Normal file
39
sw/test_code/simple_mem_test/Makefile
Normal file
@@ -0,0 +1,39 @@
|
||||
CC=../../cc65/bin/cl65
|
||||
LD=../../cc65/bin/cl65
|
||||
CFLAGS=-T -t none -I. --cpu "65C02"
|
||||
LDFLAGS=-C link.ld -m $(NAME).map
|
||||
|
||||
NAME=simple_mem_test
|
||||
|
||||
BIN=$(NAME).bin
|
||||
HEX=$(NAME).hex
|
||||
|
||||
LISTS=lists
|
||||
|
||||
SRCS=$(wildcard *.s) $(wildcard *.c)
|
||||
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
|
||||
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
|
||||
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
|
||||
|
||||
# Make sure the kernel linked to correct address, no relocation!
|
||||
all: $(HEX)
|
||||
|
||||
$(HEX): $(BIN)
|
||||
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
|
||||
|
||||
%.o: %.c $(LISTS)
|
||||
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
|
||||
|
||||
%.o: %.s $(LISTS)
|
||||
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
|
||||
|
||||
$(LISTS):
|
||||
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map
|
||||
|
||||
35
sw/test_code/simple_mem_test/link.ld
Normal file
35
sw/test_code/simple_mem_test/link.ld
Normal file
@@ -0,0 +1,35 @@
|
||||
MEMORY
|
||||
{
|
||||
ZP: start = $0, size = $100, type = rw, define = yes;
|
||||
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
|
||||
ROM: start = $F000, size = $1000, file = %O;
|
||||
}
|
||||
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp, define = yes;
|
||||
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
|
||||
BSS: load = SDRAM, type = bss, define = yes;
|
||||
HEAP: load = SDRAM, type = bss, optional = yes;
|
||||
STARTUP: load = ROM, type = ro;
|
||||
ONCE: load = ROM, type = ro, optional = yes;
|
||||
CODE: load = ROM, type = ro;
|
||||
RODATA: load = ROM, type = ro;
|
||||
VECTORS: load = ROM, type = ro, start = $FFFA;
|
||||
}
|
||||
|
||||
FEATURES {
|
||||
CONDES: segment = STARTUP,
|
||||
type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__;
|
||||
CONDES: segment = STARTUP,
|
||||
type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__;
|
||||
}
|
||||
|
||||
SYMBOLS {
|
||||
# Define the stack size for the application
|
||||
__STACKSIZE__: value = $0200, type = weak;
|
||||
__STACKSTART__: type = weak, value = $0800; # 2k stack
|
||||
}
|
||||
24
sw/test_code/simple_mem_test/main.s
Normal file
24
sw/test_code/simple_mem_test/main.s
Normal file
@@ -0,0 +1,24 @@
|
||||
.export _init, _nmi_int, _irq_int
|
||||
|
||||
.code
|
||||
|
||||
_nmi_int:
|
||||
_irq_int:
|
||||
|
||||
_init:
|
||||
lda #$aa
|
||||
sta $10
|
||||
lda #$55
|
||||
sta $11
|
||||
|
||||
lda #$ff
|
||||
sta $12
|
||||
lda #$00
|
||||
sta $13
|
||||
|
||||
lda $10
|
||||
lda $11
|
||||
lda $12
|
||||
lda $13
|
||||
|
||||
@1: bra @1
|
||||
14
sw/test_code/simple_mem_test/vectors.s
Normal file
14
sw/test_code/simple_mem_test/vectors.s
Normal file
@@ -0,0 +1,14 @@
|
||||
; ---------------------------------------------------------------------------
|
||||
; vectors.s
|
||||
; ---------------------------------------------------------------------------
|
||||
;
|
||||
; Defines the interrupt vector table.
|
||||
|
||||
.import _init
|
||||
.import _nmi_int, _irq_int
|
||||
|
||||
.segment "VECTORS"
|
||||
|
||||
.addr _nmi_int ; NMI vector
|
||||
.addr _init ; Reset vector
|
||||
.addr _irq_int ; IRQ/BRK vector
|
||||
Reference in New Issue
Block a user