From 0752220b0e2a017000e40e0ed148a40a861bb89f Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sat, 2 Mar 2024 22:46:48 -0800 Subject: [PATCH 1/4] Add basic project with cpu, ram and rom --- .gitmodules | 6 + Makefile | 6 + hw/Makefile | 6 + hw/super6502_fpga/.gitignore | 3 + hw/super6502_fpga/Makefile | 15 + hw/super6502_fpga/addr_map.mem | 5 + hw/super6502_fpga/constraints/constraints.sdc | 5 + hw/super6502_fpga/init_hex.mem | 65 +++ hw/super6502_fpga/sources.list | 14 + hw/super6502_fpga/src/rtl/super_6502_fpga.sv | 257 ++++++++++++ hw/super6502_fpga/src/sub/axi_crossbar | 1 + .../src/sub/cpu_wrapper/cpu_wrapper.sv | 391 ++++++++++++++++++ hw/super6502_fpga/src/sub/rtl-common | 1 + hw/super6502_fpga/super6502_fpga.peri.xml | 155 +++++++ hw/super6502_fpga/super6502_fpga.xml | 89 ++++ 15 files changed, 1019 insertions(+) create mode 100644 .gitmodules create mode 100644 Makefile create mode 100644 hw/Makefile create mode 100644 hw/super6502_fpga/.gitignore create mode 100644 hw/super6502_fpga/Makefile create mode 100644 hw/super6502_fpga/addr_map.mem create mode 100644 hw/super6502_fpga/constraints/constraints.sdc create mode 100644 hw/super6502_fpga/init_hex.mem create mode 100644 hw/super6502_fpga/sources.list create mode 100644 hw/super6502_fpga/src/rtl/super_6502_fpga.sv create mode 160000 hw/super6502_fpga/src/sub/axi_crossbar create mode 100644 hw/super6502_fpga/src/sub/cpu_wrapper/cpu_wrapper.sv create mode 160000 hw/super6502_fpga/src/sub/rtl-common create mode 100644 hw/super6502_fpga/super6502_fpga.peri.xml create mode 100644 hw/super6502_fpga/super6502_fpga.xml diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..4875cee --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "hw/super6502_fpga/src/sub/rtl-common"] + path = hw/super6502_fpga/src/sub/rtl-common + url = git@git.byronlathi.com:bslathi19/rtl-common.git +[submodule "hw/super6502_fpga/src/sub/axi_crossbar"] + path = hw/super6502_fpga/src/sub/axi_crossbar + url = git@git.byronlathi.com:bslathi19/axi_crossbar.git diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5429b4b --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +all: + $(MAKE) -C hw + +.PHONY: clean +clean: + $(MAKE) -C hw $@ \ No newline at end of file diff --git a/hw/Makefile b/hw/Makefile new file mode 100644 index 0000000..cacf66e --- /dev/null +++ b/hw/Makefile @@ -0,0 +1,6 @@ +all: + $(MAKE) -C super6502_fpga + +.PHONY: clean +clean: + $(MAKE) -C super6502_fpga $@ \ No newline at end of file diff --git a/hw/super6502_fpga/.gitignore b/hw/super6502_fpga/.gitignore new file mode 100644 index 0000000..0af698c --- /dev/null +++ b/hw/super6502_fpga/.gitignore @@ -0,0 +1,3 @@ +outflow +work_* +.lock diff --git a/hw/super6502_fpga/Makefile b/hw/super6502_fpga/Makefile new file mode 100644 index 0000000..8b16685 --- /dev/null +++ b/hw/super6502_fpga/Makefile @@ -0,0 +1,15 @@ +SUPER6502_FPGA_SOURCES=$(shell cat sources.list) + +SUPER6502_FPGA_BITSTREAM=outflow/super6502_fpga.hex + +SUPER6502_FPGA_PROJECT=super6502_fpga.xml + +all: $(SUPER6502_FPGA_BITSTREAM) + +$(SUPER6502_FPGA_BITSTREAM): $(SUPER6502_FPGA_SOURCES) $(SUPER6502_FPGA_PROJECT) + efx_run.py $(SUPER6502_FPGA_PROJECT) + +.PHONY: clean +clean: + rm -rf work_* + rm -rf outflow \ No newline at end of file diff --git a/hw/super6502_fpga/addr_map.mem b/hw/super6502_fpga/addr_map.mem new file mode 100644 index 0000000..3d631b3 --- /dev/null +++ b/hw/super6502_fpga/addr_map.mem @@ -0,0 +1,5 @@ +@00000000 +00000000 +000001ff +0000ff00 +0000ffff \ No newline at end of file diff --git a/hw/super6502_fpga/constraints/constraints.sdc b/hw/super6502_fpga/constraints/constraints.sdc new file mode 100644 index 0000000..f294bb2 --- /dev/null +++ b/hw/super6502_fpga/constraints/constraints.sdc @@ -0,0 +1,5 @@ +create_clock -period 5.00 i_sdrclk +create_clock -period 5.00 i_tACclk +create_clock -period 10.00 i_sysclk + +create_generated_clock -source i_sysclk -divide_by 50 clk_cpu diff --git a/hw/super6502_fpga/init_hex.mem b/hw/super6502_fpga/init_hex.mem new file mode 100644 index 0000000..b6697d2 --- /dev/null +++ b/hw/super6502_fpga/init_hex.mem @@ -0,0 +1,65 @@ +@00000000 +8d00a9 +200cd02 +801a03d0 +fe80f5 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +ff000000 +ff00ff00 diff --git a/hw/super6502_fpga/sources.list b/hw/super6502_fpga/sources.list new file mode 100644 index 0000000..e717faa --- /dev/null +++ b/hw/super6502_fpga/sources.list @@ -0,0 +1,14 @@ +src/rtl/super_6502_fpga.sv +src/sub/axi_crossbar/src/rtl/axi_crossbar.sv +src/sub/axi_crossbar/src/rtl/axi_master.sv +src/sub/axi_crossbar/src/rtl/axi_slave.sv +src/sub/axi_crossbar/src/rtl/rr_scheduler.sv +src/sub/axi_crossbar/src/rtl/slave_addr_decoder.sv +src/sub/cpu_wrapper/cpu_wrapper.sv +src/sub/rtl-common/src/rtl/async_fifo.sv +src/sub/rtl-common/src/rtl/axi4_lite_ram.sv +src/sub/rtl-common/src/rtl/axi4_lite_rom.sv +src/sub/rtl-common/src/rtl/ff_cdc.sv +src/sub/rtl-common/src/rtl/shallow_async_fifo.sv +src/sub/rtl-common/src/rtl/sync_fifo.sv + diff --git a/hw/super6502_fpga/src/rtl/super_6502_fpga.sv b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv new file mode 100644 index 0000000..13b9ae4 --- /dev/null +++ b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv @@ -0,0 +1,257 @@ +module super6502_fpga( + input logic i_sysclk, // Controller Clock (100MHz) + input logic i_sdrclk, // t_su and t_wd clock (200MHz) + input logic i_tACclk, // t_ac clock (200MHz) + input clk_cpu, + + input button_reset, + + input pll_cpu_locked, + output logic pll_cpu_reset, + + input i_pll_locked, + output logic o_pll_reset, + + input [7:0] i_cpu0_data_from_cpu, + input i_cpu0_sync, + input i_cpu0_rwb, + input logic [15:0] i_cpu0_addr, + output logic [7:0] o_cpu0_data_from_dut, + output logic [7:0] o_cpu0_data_oe, + output logic o_cpu0_irqb, + output logic o_cpu0_nmib, + output logic o_cpu0_rdy, + output logic o_cpu0_reset +); + + +localparam ADDR_WIDTH = 32; +localparam DATA_WIDTH = 32; + + +assign pll_cpu_reset = '1; +assign o_pll_reset = '1; + +assign o_cpu0_nmib = '1; + +assign o_clk_phi2 = clk_cpu; + +assign o_cpu0_data_oe = {8{i_cpu0_rwb}}; + + +logic master_reset; + +assign master_reset = button_reset; + +logic cpu0_AWVALID; +logic cpu0_AWREADY; +logic [ADDR_WIDTH-1:0] cpu0_AWADDR; +logic cpu0_WVALID; +logic cpu0_WREADY; +logic [DATA_WIDTH-1:0] cpu0_WDATA; +logic [DATA_WIDTH/8-1:0] cpu0_WSTRB; +logic cpu0_BVALID; +logic cpu0_BREADY; +logic [1:0] cpu0_BRESP; +logic cpu0_ARVALID; +logic cpu0_ARREADY; +logic [ADDR_WIDTH-1:0] cpu0_ARADDR; +logic cpu0_RVALID; +logic cpu0_RREADY; +logic [DATA_WIDTH-1:0] cpu0_RDATA; +logic [1:0] cpu0_RRESP; + + +logic ram_awvalid; +logic ram_awready; +logic [ADDR_WIDTH-1:0] ram_awaddr; +logic ram_wvalid; +logic ram_wready; +logic [DATA_WIDTH-1:0] ram_wdata; +logic [DATA_WIDTH/8-1:0] ram_wstrb; +logic ram_bvalid; +logic ram_bready; +logic [1:0] ram_bresp; +logic ram_arvalid; +logic ram_arready; +logic [ADDR_WIDTH-1:0] ram_araddr; +logic ram_rvalid; +logic ram_rready; +logic [DATA_WIDTH-1:0] ram_rdata; +logic [1:0] ram_rresp; + +logic rom_awvalid; +logic rom_awready; +logic [ADDR_WIDTH-1:0] rom_awaddr; +logic rom_wvalid; +logic rom_wready; +logic [DATA_WIDTH-1:0] rom_wdata; +logic [DATA_WIDTH/8-1:0] rom_wstrb; +logic rom_bvalid; +logic rom_bready; +logic [1:0] rom_bresp; +logic rom_arvalid; +logic rom_arready; +logic [ADDR_WIDTH-1:0] rom_araddr; +logic rom_rvalid; +logic rom_rready; +logic [DATA_WIDTH-1:0] rom_rdata; +logic [1:0] rom_rresp; + + +cpu_wrapper u_cpu_wrapper_0( + .i_clk_cpu (clk_cpu), + .i_clk_100 (i_sysclk), + .i_rst (~master_reset), + + .o_cpu_rst (o_cpu0_reset), + .o_cpu_rdy (o_cpu0_rdy), + .o_cpu_be (), + .o_cpu_irqb (o_cpu0_irqb), + .o_cpu_nmib (), + .o_cpu_sob (), + + .i_cpu_rwb (i_cpu0_rwb), + .i_cpu_sync (i_cpu0_sync), + .i_cpu_vpb ('0), + .i_cpu_mlb ('0), + + .i_cpu_addr (i_cpu0_addr), + .i_cpu_data (i_cpu0_data_from_cpu), + .o_cpu_data (o_cpu0_data_from_dut), + + .o_AWVALID (cpu0_AWVALID), + .i_AWREADY (cpu0_AWREADY), + .o_AWADDR (cpu0_AWADDR), + .o_WVALID (cpu0_WVALID), + .i_WREADY (cpu0_WREADY), + .o_WDATA (cpu0_WDATA), + .o_WSTRB (cpu0_WSTRB), + .i_BVALID (cpu0_BVALID), + .o_BREADY (cpu0_BREADY), + .i_BRESP (cpu0_BRESP), + .o_ARVALID (cpu0_ARVALID), + .i_ARREADY (cpu0_ARREADY), + .o_ARADDR (cpu0_ARADDR), + .i_RVALID (cpu0_RVALID), + .o_RREADY (cpu0_RREADY), + .i_RDATA (cpu0_RDATA), + .i_RRESP (cpu0_RRESP), + + .i_irq('0), + .i_nmi('0) +); + + +axi_crossbar #( + .N_INITIATORS(1), + .N_TARGETS(2) +) u_crossbar ( + .clk(i_sysclk), + .rst(~master_reset), + + .ini_araddr ({cpu0_ARADDR }), + .ini_arvalid ({cpu0_ARVALID }), + .ini_arready ({cpu0_ARREADY }), + .ini_rdata ({cpu0_RDATA }), + .ini_rresp ({cpu0_RRESP }), + .ini_rvalid ({cpu0_RVALID }), + .ini_rready ({cpu0_RREADY }), + .ini_awaddr ({cpu0_AWADDR }), + .ini_awready ({cpu0_AWREADY }), + .ini_awvalid ({cpu0_AWVALID }), + .ini_wvalid ({cpu0_WVALID }), + .ini_wready ({cpu0_WREADY }), + .ini_wdata ({cpu0_WDATA }), + .ini_wstrb ({cpu0_WSTRB }), + .ini_bresp ({cpu0_BRESP }), + .ini_bvalid ({cpu0_BVALID }), + .ini_bready ({cpu0_BREADY }), + + .tgt_araddr ({ram_araddr, rom_araddr }), + .tgt_arvalid ({ram_arvalid, rom_arvalid }), + .tgt_arready ({ram_arready, rom_arready }), + .tgt_rdata ({ram_rdata, rom_rdata }), + .tgt_rresp ({ram_rresp, rom_rresp }), + .tgt_rvalid ({ram_rvalid, rom_rvalid }), + .tgt_rready ({ram_rready, rom_rready }), + .tgt_awaddr ({ram_awaddr, rom_awaddr }), + .tgt_awvalid ({ram_awvalid, rom_awvalid }), + .tgt_awready ({ram_awready, rom_awready }), + .tgt_wdata ({ram_wdata, rom_wdata }), + .tgt_wvalid ({ram_wvalid, rom_wvalid }), + .tgt_wready ({ram_wready, rom_wready }), + .tgt_wstrb ({ram_wstrb, rom_wstrb }), + .tgt_bresp ({ram_bresp, rom_bresp }), + .tgt_bvalid ({ram_bvalid, rom_bvalid }), + .tgt_bready ({ram_bready, rom_bready }) +); + +axi4_lite_rom #( + .ROM_SIZE(8), + .ROM_INIT_FILE("init_hex.mem") +) u_rom ( + .i_clk(i_sysclk), + .i_rst(~master_reset), + + .o_AWREADY(rom_awready), + .o_WREADY(rom_wready), + + .o_BVALID(rom_bvalid), + .i_BREADY(rom_bready), + .o_BRESP(rom_bresp), + + .i_ARVALID(rom_arvalid), + .o_ARREADY(rom_arready), + .i_ARADDR(rom_araddr), + .i_ARPROT('0), + + .o_RVALID(rom_rvalid), + .i_RREADY(rom_rready), + .o_RDATA(rom_rdata), + .o_RRESP(rom_rresp), + + .i_AWVALID(rom_awvalid), + .i_AWADDR(rom_awaddr), + .i_AWPROT('0), + + .i_WVALID(rom_wvalid), + .i_WDATA(rom_wdata), + .i_WSTRB(rom_wstrb) +); + +axi4_lite_ram #( + .RAM_SIZE(9) +) u_ram( + .i_clk(i_sysclk), + .i_rst(~master_reset), + + .o_AWREADY(ram_awready), + .o_WREADY(ram_wready), + + .o_BVALID(ram_bvalid), + .i_BREADY(ram_bready), + .o_BRESP(ram_bresp), + + .i_ARVALID(ram_arvalid), + .o_ARREADY(ram_arready), + .i_ARADDR(ram_araddr), + .i_ARPROT('0), + + .o_RVALID(ram_rvalid), + .i_RREADY(ram_rready), + .o_RDATA(ram_rdata), + .o_RRESP(ram_rresp), + + .i_AWVALID(ram_awvalid), + .i_AWADDR(ram_awaddr), + .i_AWPROT('0), + + .i_WVALID(ram_wvalid), + .i_WDATA(ram_wdata), + .i_WSTRB(ram_wstrb) +); + + + +endmodule \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/axi_crossbar b/hw/super6502_fpga/src/sub/axi_crossbar new file mode 160000 index 0000000..5c61f56 --- /dev/null +++ b/hw/super6502_fpga/src/sub/axi_crossbar @@ -0,0 +1 @@ +Subproject commit 5c61f56e7b66853abe2a079745d1cf010bd18175 diff --git a/hw/super6502_fpga/src/sub/cpu_wrapper/cpu_wrapper.sv b/hw/super6502_fpga/src/sub/cpu_wrapper/cpu_wrapper.sv new file mode 100644 index 0000000..b0a20fd --- /dev/null +++ b/hw/super6502_fpga/src/sub/cpu_wrapper/cpu_wrapper.sv @@ -0,0 +1,391 @@ +module cpu_wrapper #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32 +)( + /* Clocks and Reset */ + input logic i_clk_cpu, + input logic i_clk_100, + input logic i_rst, + + /* CPU Control Signals */ + output logic o_cpu_rst, + output logic o_cpu_rdy, + output logic o_cpu_be, + output logic o_cpu_irqb, + output logic o_cpu_nmib, + output logic o_cpu_sob, + + /* CPU Status Signals */ + input logic i_cpu_rwb, + input logic i_cpu_sync, + input logic i_cpu_vpb, + input logic i_cpu_mlb, + + /* CPU Address and Data */ + input logic [15:0] i_cpu_addr, + input logic [7:0] i_cpu_data, + output logic [7:0] o_cpu_data, + + /* AXI4-Lite signals */ + output logic o_AWVALID, + input logic i_AWREADY, + output logic [ADDR_WIDTH-1:0] o_AWADDR, + output logic [2:0] o_AWPROT, + + output logic o_WVALID, + input logic i_WREADY, + output logic [DATA_WIDTH-1:0] o_WDATA, + output logic [DATA_WIDTH/8-1:0] o_WSTRB, + + input logic i_BVALID, + output logic o_BREADY, + input logic [1:0] i_BRESP, + + output logic o_ARVALID, + input logic i_ARREADY, + output logic [ADDR_WIDTH-1:0] o_ARADDR, + output logic [2:0] o_ARPROT, + + input logic i_RVALID, + output logic o_RREADY, + input logic [DATA_WIDTH-1:0] i_RDATA, + input logic [1:0] i_RRESP, + + /* interrupt signals */ + input logic i_irq, + input logic i_nmi +); + +typedef enum logic [3:0] { + RESET, + IDLE, + ADDR_CONTROL, + READ_VALID, + READ_DATA, + WRITE_VALID, + GET_WRITE_DATA, + WRITE_DATA, + STALL +} state_t; + +state_t state, state_next; + +logic w_status_empty; +logic w_status_r_en; + +logic r_rwb, r_sync, r_vpb, r_mlb; +logic r_rwb_next, r_sync_next, r_vpb_next, r_mlb_next; + +logic [15:0] r_addr, r_addr_next; + +logic w_write_data_en; +logic [7:0] r_write_data, r_write_data_next; +logic w_write_data_empty; + +logic [2:0] counter; +logic w_reset; + +always @(posedge i_clk_cpu) begin + if (i_rst) begin + counter <= '1; + end else if (counter) begin + counter <= counter - 3'd1; + end +end + +assign w_reset = |counter; + +ff_cdc #( + .RESET_VAL(0) +) u_cpu_rst_cdc ( + .rst(i_rst), + .clk(i_clk_cpu), + .data_a(~w_reset), + .data_b(o_cpu_rst) +); + +ff_cdc u_cpu_irq_cdc ( + .rst(i_rst), + .clk(i_clk_cpu), + .data_a(~i_irq), + .data_b(o_cpu_irqb) +); + +ff_cdc u_cpu_nmi_cdc ( + .rst(i_rst), + .clk(i_clk_cpu), + .data_a(~i_nmi), + .data_b(o_cpu_nmib) +); + +// This fifo says it has a bug with back to back writes, but maybe that +// is only for fast -> slow? this is slow -> fast. +// async_fifo #( +// .WIDTH(20), +// .A_SIZE(3) +// ) u_status_addr_fifo ( +// .i_rst_a(o_cpu_rst), +// .i_clk_a(i_clk_cpu), +// .i_rst_b(i_rst), +// .i_clk_b(i_clk_100), +// .w_en('1), // investigate this +// .i_data({i_cpu_rwb, i_cpu_sync, i_cpu_vpb, i_cpu_mlb, i_cpu_addr}), +// .o_full(), +// .r_en(w_status_r_en), +// .o_data({r_rwb_next, r_sync_next, r_vpb_next, r_mlb_next, r_addr_next}), +// .o_empty(w_status_empty) +// ); + + +logic [1:0] flag; + +assign w_status_empty = ~flag[0]; + +assign r_rwb_next = i_cpu_rwb; +assign r_sync_next = i_cpu_sync; +assign r_vpb_next = i_cpu_vpb; +assign r_mlb_next = i_cpu_mlb; +assign r_addr_next = i_cpu_addr; + +always @(posedge i_clk_100 or posedge i_rst) begin + if (i_rst) begin + flag <= '0; + end else begin + if (i_clk_cpu) begin + if (flag == '0) begin + flag <= 2'h1; + end else if (flag == 2'h1) begin + flag <= 2'h2; + end + end else begin + flag <= '0; + end + end +end + +// // This uses inverted clock, remember in sdc? +// async_fifo #( +// .WIDTH(8), +// .A_SIZE(3) +// ) u_write_data_fifo ( +// .i_rst_a(o_cpu_rst), +// .i_clk_a(~i_clk_cpu), +// .i_rst_b(i_rst), +// .i_clk_b(i_clk_100), +// .w_en('1), +// .i_data(i_cpu_data), +// .o_full(), +// .r_en(w_write_data_en), +// .o_data(r_write_data_next), +// .o_empty(w_write_data_empty) +// ); + + +// Really bad double flop bus +always @(negedge i_clk_cpu) begin + r_write_data_next <= i_cpu_data; +end + + +logic [1:0] flag2; + +assign w_write_data_empty = ~flag2[0]; + +always @(posedge i_clk_100 or posedge i_rst) begin + if (i_rst) begin + flag2 <= '0; + end else begin + if (~i_clk_cpu) begin + if (flag2 == '0) begin + flag2 <= 2'h1; + end else if (flag2 == 2'h1) begin + flag2 <= 2'h2; + end + end else begin + flag2 <= '0; + end + end +end + +localparam MAX_DELAY = 4; + +logic [7:0] cycle_counter; +logic too_late; + +logic [2:0] rdy_dly; +logic potential_rdy; +logic did_delay, did_delay_next; + +assign potential_rdy = |rdy_dly; + +assign too_late = cycle_counter > MAX_DELAY ? 1 : 0; + +always_ff @(posedge i_clk_100 or posedge i_rst) begin + if (i_rst) begin + cycle_counter <= '0; + rdy_dly <= '0; + end else begin + if (i_clk_cpu) begin + cycle_counter <= cycle_counter + 1; + end else begin + cycle_counter <= '0; + end + + rdy_dly <= {rdy_dly[1:0], too_late}; + end +end + +logic [7:0] read_data, read_data_next; +assign o_cpu_data = read_data; + +always_comb begin + state_next = state; + + // Set defaults + o_AWVALID = '0; + o_AWADDR = '0; + o_AWPROT = '0; + o_WVALID = '0; + o_WDATA = '0; + o_WSTRB = '0; + o_BREADY = '0; + o_ARVALID = '0; + o_ARADDR = '0; + o_ARPROT = '0; + o_RREADY = '0; + + o_cpu_rdy = '1; + + read_data_next = read_data; + did_delay_next = did_delay; + + case (state) + RESET: begin + // Is this a CDC violation? + if (i_cpu_addr == 16'hFFFC) begin + state_next = IDLE; + end + end + + IDLE: begin + if (~w_status_empty) begin + state_next = ADDR_CONTROL; + end + + did_delay_next = '0; + end + + ADDR_CONTROL: begin + if (r_rwb) begin + state_next = READ_VALID; + end else begin + state_next = WRITE_VALID; + end + end + + READ_VALID: begin + o_ARVALID = '1; + // $display("%x %x %x", o_ARVALID, i_ARREADY, o_ARVALID & i_ARREADY); + + if (o_ARVALID & i_ARREADY) begin + // $display("AHHHHHH"); + state_next = READ_DATA; + // $display("next state: %x", state_next); + end + + o_ARADDR = {r_addr[15:2], 2'b0}; + end + + READ_DATA: begin + if (potential_rdy) begin + state_next = READ_DATA; + o_cpu_rdy = ~potential_rdy; + did_delay_next = '1; + end + + if (i_RVALID) begin + if (did_delay || potential_rdy) begin + state_next = STALL; + end else begin + state_next = IDLE; + end + read_data_next = i_RDATA[8*r_addr[1:0] +: 8]; + end + + o_RREADY = '1; + end + + WRITE_VALID: begin + if (~w_write_data_empty) begin + state_next = WRITE_DATA; + end + end + + GET_WRITE_DATA: begin + $error("GET_WRITE_DATA not implemented"); + state_next = IDLE; + end + + WRITE_DATA: begin + o_AWVALID = '1; + o_AWADDR = {r_addr[15:2], 2'b0}; + o_WVALID = '1; + o_WSTRB = 4'b1 << r_addr[1:0]; + o_WDATA = r_write_data << 8*r_addr[1:0]; + + o_BREADY = '1; + if (i_BVALID) begin + state_next = IDLE; + end + end + + STALL: begin + // kind of dumb + if (cycle_counter == 1) begin + state_next = IDLE; + end + + o_cpu_rdy = ~potential_rdy; + end + + default: begin + // $error("Invalid state"); + state_next = IDLE; + end + + endcase +end + +always_ff @(posedge i_clk_100 or posedge i_rst) begin + if (i_rst) begin + r_rwb <= '1; // start as 1 to indicate read. + r_sync <= '0; + r_vpb <= '0; + r_mlb <= '0; + r_addr <= '0; + read_data <= '0; + r_write_data <= '0; + did_delay <= '0; + + state <= RESET; + end else begin + if (~w_status_empty) begin + w_status_r_en <= '1; + r_rwb <= r_rwb_next; + r_sync <= r_sync_next; + r_vpb <= r_vpb_next; + r_mlb <= r_mlb_next; + r_addr <= r_addr_next; + end else begin + w_status_r_en <= '0; + end + + read_data <= read_data_next; + state <= state_next; + did_delay <= did_delay_next; + + r_write_data <= r_write_data_next; + end +end + +endmodule \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/rtl-common b/hw/super6502_fpga/src/sub/rtl-common new file mode 160000 index 0000000..170285d --- /dev/null +++ b/hw/super6502_fpga/src/sub/rtl-common @@ -0,0 +1 @@ +Subproject commit 170285d7abf968dbe9cb6f3d919039bc117eef60 diff --git a/hw/super6502_fpga/super6502_fpga.peri.xml b/hw/super6502_fpga/super6502_fpga.peri.xml new file mode 100644 index 0000000..6be3434 --- /dev/null +++ b/hw/super6502_fpga/super6502_fpga.peri.xml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hw/super6502_fpga/super6502_fpga.xml b/hw/super6502_fpga/super6502_fpga.xml new file mode 100644 index 0000000..71190d7 --- /dev/null +++ b/hw/super6502_fpga/super6502_fpga.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 31b3fdcfc9590bee90f33816701010792017ddd7 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sat, 2 Mar 2024 22:55:39 -0800 Subject: [PATCH 2/4] Add basic ci and separate hw from all target --- .gitlab-ci.yml | 15 +++++++++++++++ Makefile | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..6a5628b --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,15 @@ +variables: + GIT_SUBMODULE_STRATEGY: recursive + +stages: + - build + +build hw: + stage: build + tags: + - efinity + - linux + script: + - source init_env.sh + - make hw + diff --git a/Makefile b/Makefile index 5429b4b..7b9cb5d 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,7 @@ -all: +all: hw + +.PHONY: hw +hw: $(MAKE) -C hw .PHONY: clean From 6213d2a2276d08b76db80a5d0f6f7467416ec6b2 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sat, 2 Mar 2024 23:47:13 -0800 Subject: [PATCH 3/4] Use relative submodule paths for ci --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 4875cee..07a7976 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "hw/super6502_fpga/src/sub/rtl-common"] path = hw/super6502_fpga/src/sub/rtl-common - url = git@git.byronlathi.com:bslathi19/rtl-common.git + url = ../rtl-common.git [submodule "hw/super6502_fpga/src/sub/axi_crossbar"] path = hw/super6502_fpga/src/sub/axi_crossbar - url = git@git.byronlathi.com:bslathi19/axi_crossbar.git + url = ../axi_crossbar.git From cd1dfa39cb4c21abbb2e7896f3341997b15e873f Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 3 Mar 2024 09:45:04 -0800 Subject: [PATCH 4/4] Fix PLL settings, add cpu output clock --- hw/super6502_fpga/src/rtl/super_6502_fpga.sv | 4 ++-- hw/super6502_fpga/super6502_fpga.peri.xml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/super6502_fpga/src/rtl/super_6502_fpga.sv b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv index 13b9ae4..62429b3 100644 --- a/hw/super6502_fpga/src/rtl/super_6502_fpga.sv +++ b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv @@ -21,14 +21,14 @@ module super6502_fpga( output logic o_cpu0_irqb, output logic o_cpu0_nmib, output logic o_cpu0_rdy, - output logic o_cpu0_reset + output logic o_cpu0_reset, + output logic o_clk_phi2 ); localparam ADDR_WIDTH = 32; localparam DATA_WIDTH = 32; - assign pll_cpu_reset = '1; assign o_pll_reset = '1; diff --git a/hw/super6502_fpga/super6502_fpga.peri.xml b/hw/super6502_fpga/super6502_fpga.peri.xml index 6be3434..a664a30 100644 --- a/hw/super6502_fpga/super6502_fpga.peri.xml +++ b/hw/super6502_fpga/super6502_fpga.peri.xml @@ -1,5 +1,5 @@ - + @@ -143,11 +143,11 @@ - - - - - + + + + +