From d37e32ec64abce402415257d51a9a33ec17df070 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Sep 2023 23:27:54 -0700 Subject: [PATCH 01/57] Add sim cpu --- .gitmodules | 3 +++ hw/efinix_fpga/simulation/sim_top.sv | 12 ++++++++++++ hw/efinix_fpga/simulation/verilog-6502 | 1 + 3 files changed, 16 insertions(+) create mode 100644 hw/efinix_fpga/simulation/sim_top.sv create mode 160000 hw/efinix_fpga/simulation/verilog-6502 diff --git a/.gitmodules b/.gitmodules index 21b2181..6d2a279 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "sw/cc65"] path = sw/cc65 url = https://git.byronlathi.com/bslathi19/cc65 +[submodule "hw/efinix_fpga/simulation/verilog-6502"] + path = hw/efinix_fpga/simulation/verilog-6502 + url = https://git.byronlathi.com/bslathi19/verilog-6502 diff --git a/hw/efinix_fpga/simulation/sim_top.sv b/hw/efinix_fpga/simulation/sim_top.sv new file mode 100644 index 0000000..81ceefc --- /dev/null +++ b/hw/efinix_fpga/simulation/sim_top.sv @@ -0,0 +1,12 @@ +module sim_top(); + +//TODO: this +cpu_65c02 u_cpu(); + +//TODO: also this +super6502 u_dut(); + +//TODO: decide what to do here +memory u_mem(); + +endmodule \ No newline at end of file diff --git a/hw/efinix_fpga/simulation/verilog-6502 b/hw/efinix_fpga/simulation/verilog-6502 new file mode 160000 index 0000000..a5f605d --- /dev/null +++ b/hw/efinix_fpga/simulation/verilog-6502 @@ -0,0 +1 @@ +Subproject commit a5f605d00d22095532cc32aa7a481465b1bdca17 From e50203dd3ede3ad47e9f24c5923328ae0ec103c6 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Thu, 21 Sep 2023 19:23:31 -0700 Subject: [PATCH 02/57] Add generic SDR --- hw/efinix_fpga/simulation/generic_sdr.v | 1145 +++++++++++++++++ .../super6502_sdram_controller_define.vh | 23 + 2 files changed, 1168 insertions(+) create mode 100644 hw/efinix_fpga/simulation/generic_sdr.v create mode 100644 hw/efinix_fpga/simulation/super6502_sdram_controller_define.vh diff --git a/hw/efinix_fpga/simulation/generic_sdr.v b/hw/efinix_fpga/simulation/generic_sdr.v new file mode 100644 index 0000000..912d519 --- /dev/null +++ b/hw/efinix_fpga/simulation/generic_sdr.v @@ -0,0 +1,1145 @@ +/************************************************************************** +* +* File Name: sdr.v +* Version: 2.2 +* Date: October 12th, 2010 +* Model: BUS Functional +* Simulator: Model Technology +* +* Dependencies: None +* +* Email: modelsupport@micron.com +* Company: Micron Technology, Inc. +* +* Description: Micron SDRAM Verilog model +* +* Limitation: - Doesn't check for refresh timing +* +* Note: - Set simulator resolution to "ps" accuracy +* - Set Debug = 0 to disable $display messages +* +* Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY +* WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY +* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR +* A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. +* +* Copyright � 2001 Micron Semiconductor Products, Inc. +* All rights researved +* +* Rev Author Date Changes +* --- -------------------------- --------------------------------------- +* 2.3 SH 05/12/2016 - Update tAC, tHZ timing +* Micron Technology Inc. +* +* 2.2 SH 10/12/2010 - Combine all parts into sdr_parameters.vh +* Micron Technology Inc. +* +* 2.1 SH 06/06/2002 - Typo in bank multiplex +* Micron Technology Inc. +* +* 2.0 SH 04/30/2002 - Second release +* Micron Technology Inc. +* +**************************************************************************/ + +`timescale 1ns / 1ps +`define x8 +`define CLK_200 +`define SYS_CLK_100 + +module generic_sdr (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm); + +`include "super6502_sdram_controller_define.vh" + +parameter tCK = 1000/fCK_MHz; // tCK ns Nominal Clock Cycle Time +`ifdef CLK_200 + parameter real tAC3 = 4.5; // tAC3 ns Access time from CLK (pos edge) CL = 3 + parameter real tAC2 = 4.5; // tAC2 ns Access time from CLK (pos edge) CL = 2 + parameter real tAC1 = 4.5; // tAC1 ns Parameter definition for compilation - CL = 1 illegal for sg75 +`elsif CLK_166 + parameter real tAC3 = 5.4; // tAC3 ns Access time from CLK (pos edge) CL = 3 + parameter real tAC2 = 5.4; // tAC2 ns Access time from CLK (pos edge) CL = 2 + parameter real tAC1 = 5.4; // tAC1 ns Parameter definition for compilation - CL = 1 illegal for sg75 +`elsif CLK_133 + parameter real tAC3 = 6.0; // tAC3 ns Access time from CLK (pos edge) CL = 3 + parameter real tAC2 = 6.0; // tAC2 ns Access time from CLK (pos edge) CL = 2 + parameter real tAC1 = 6.0; // tAC1 ns Parameter definition for compilation - CL = 1 illegal for sg75 +`endif + +`ifdef CLK_200 + parameter real tHZ3 = 4.5; // tHZ3 ns Data Out High Z time - CL = 3 + parameter real tHZ2 = 4.5; // tHZ2 ns Data Out High Z time - CL = 2 + parameter real tHZ1 = 4.5; // tHZ1 ns Parameter definition for compilation - CL = 1 illegal for sg75 +`elsif CLK_166 + parameter real tHZ3 = 5.4; // tHZ3 ns Data Out High Z time - CL = 3 + parameter real tHZ2 = 5.4; // tHZ2 ns Data Out High Z time - CL = 2 + parameter real tHZ1 = 5.4; // tHZ1 ns Parameter definition for compilation - CL = 1 illegal for sg75 +`elsif CLK_133 + parameter real tHZ3 = 6.0; // tHZ3 ns Data Out High Z time - CL = 3 + parameter real tHZ2 = 6.0; // tHZ2 ns Data Out High Z time - CL = 2 + parameter real tHZ1 = 6.0; // tHZ1 ns Parameter definition for compilation - CL = 1 illegal for sg75 +`endif + +parameter tOH = 2.7; // tOH ns Data Out Hold time +parameter tRRD = 2.0; // tRRD tCK Active bank a to Active bank b command time (2 * tCK) +parameter tWRa = tCK; // tWR ns Write recovery time (auto-precharge mode - must add 1 CLK) +parameter tWRm = 2*tCK; // tWR ns Write recovery time +parameter ADDR_BITS = ROW_WIDTH; // Set this parameter to control how many Address bits are used +parameter ROW_BITS = ROW_WIDTH; // Set this parameter to control how many Row bits are used +parameter COL_BITS = COL_WIDTH; // Set this parameter to control how many Column bits are used +parameter DQ_BITS = DQ_WIDTH; // Set this parameter to control how many Data bits are used +parameter DM_BITS = 1; // Set this parameter to control how many DM bits are used +parameter BA_BITS = BA_WIDTH; // Bank bits +parameter mem_sizes = 2**(ROW_BITS+COL_BITS) - 1; + + input Clk; + input Cke; + input Cs_n; + input Ras_n; + input Cas_n; + input We_n; + input [ADDR_BITS - 1 : 0] Addr; + input [BA_BITS - 1 : 0] Ba; + inout [DQ_BITS - 1 : 0] Dq; + input [DM_BITS - 1 : 0] Dqm; + + reg [DQ_BITS - 1 : 0] Bank0 [0 : mem_sizes]; + reg [DQ_BITS - 1 : 0] Bank1 [0 : mem_sizes]; + reg [DQ_BITS - 1 : 0] Bank2 [0 : mem_sizes]; + reg [DQ_BITS - 1 : 0] Bank3 [0 : mem_sizes]; + + reg [1 : 0] Bank_addr [0 : 3]; // Bank Address Pipeline + reg [COL_BITS - 1 : 0] Col_addr [0 : 3]; // Column Address Pipeline + reg [3 : 0] Command [0 : 3]; // Command Operation Pipeline + reg [1 : 0] Dqm_reg0, Dqm_reg1; // DQM Operation Pipeline + reg [ADDR_BITS - 1 : 0] B0_row_addr, B1_row_addr, B2_row_addr, B3_row_addr; + + reg [ADDR_BITS - 1 : 0] Mode_reg; + reg [DQ_BITS - 1 : 0] Dq_reg, Dq_dqm; + reg [COL_BITS - 1 : 0] Col_temp, Burst_counter; + + reg Act_b0, Act_b1, Act_b2, Act_b3; // Bank Activate + reg Pc_b0, Pc_b1, Pc_b2, Pc_b3; // Bank Precharge + + reg [1 : 0] Bank_precharge [0 : 3]; // Precharge Command + reg A10_precharge [0 : 3]; // Addr[10] = 1 (All banks) + reg Auto_precharge [0 : 3]; // RW Auto Precharge (Bank) + reg Read_precharge [0 : 3]; // R Auto Precharge + reg Write_precharge [0 : 3]; // W Auto Precharge + reg RW_interrupt_read [0 : 3]; // RW Interrupt Read with Auto Precharge + reg RW_interrupt_write [0 : 3]; // RW Interrupt Write with Auto Precharge + reg [1 : 0] RW_interrupt_bank; // RW Interrupt Bank + integer RW_interrupt_counter [0 : 3]; // RW Interrupt Counter + integer Count_precharge [0 : 3]; // RW Auto Precharge Counter + + reg Data_in_enable; + reg Data_out_enable; + + reg [1 : 0] Bank, Prev_bank; + reg [ADDR_BITS - 1 : 0] Row; + reg [COL_BITS - 1 : 0] Col, Col_brst; + + // Internal system clock + reg CkeZ, Sys_clk; + + // Commands Decode + wire Active_enable = ~Cs_n & ~Ras_n & Cas_n & We_n; + wire Aref_enable = ~Cs_n & ~Ras_n & ~Cas_n & We_n; + wire Burst_term = ~Cs_n & Ras_n & Cas_n & ~We_n; + wire Mode_reg_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n; + wire Prech_enable = ~Cs_n & ~Ras_n & Cas_n & ~We_n; + wire Read_enable = ~Cs_n & Ras_n & ~Cas_n & We_n; + wire Write_enable = ~Cs_n & Ras_n & ~Cas_n & ~We_n; + + // Burst Length Decode + wire Burst_length_1 = ~Mode_reg[2] & ~Mode_reg[1] & ~Mode_reg[0]; + wire Burst_length_2 = ~Mode_reg[2] & ~Mode_reg[1] & Mode_reg[0]; + wire Burst_length_4 = ~Mode_reg[2] & Mode_reg[1] & ~Mode_reg[0]; + wire Burst_length_8 = ~Mode_reg[2] & Mode_reg[1] & Mode_reg[0]; + wire Burst_length_f = Mode_reg[2] & Mode_reg[1] & Mode_reg[0]; + + // CAS Latency Decode + wire [2 : 0] Cas_latency = {Mode_reg[6], Mode_reg[5], Mode_reg[4]}; + + // Write Burst Mode + wire Write_burst_mode = Mode_reg[9]; + + wire Debug = 1'b1; // Debug messages : 1 = On + wire Dq_chk = Sys_clk & Data_in_enable; // Check setup/hold time for DQ + + assign Dq = Dq_reg; // DQ buffer + + // Commands Operation + `define ACT 0 + `define NOP 1 + `define READ 2 + `define WRITE 3 + `define PRECH 4 + `define A_REF 5 + `define BST 6 + `define LMR 7 + + // These timing dynamically adjust based on CAS Latency + time tAC, tHZ; + + // Timing Check variable + time MRD_chk; + time WR_chkm [0 : 3]; + time RFC_chk, RRD_chk; + time RC_chk0, RC_chk1, RC_chk2, RC_chk3; + time RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3; + time RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3; + time RP_chk0, RP_chk1, RP_chk2, RP_chk3; + + initial begin + Dq_reg = {DQ_BITS{1'bz}}; + Data_in_enable = 0; Data_out_enable = 0; + Act_b0 = 1; Act_b1 = 1; Act_b2 = 1; Act_b3 = 1; + Pc_b0 = 0; Pc_b1 = 0; Pc_b2 = 0; Pc_b3 = 0; + WR_chkm[0] = 0; WR_chkm[1] = 0; WR_chkm[2] = 0; WR_chkm[3] = 0; + RW_interrupt_read[0] = 0; RW_interrupt_read[1] = 0; RW_interrupt_read[2] = 0; RW_interrupt_read[3] = 0; + RW_interrupt_write[0] = 0; RW_interrupt_write[1] = 0; RW_interrupt_write[2] = 0; RW_interrupt_write[3] = 0; + MRD_chk = 0; RFC_chk = 0; RRD_chk = 0; + RAS_chk0 = 0; RAS_chk1 = 0; RAS_chk2 = 0; RAS_chk3 = 0; + RCD_chk0 = 0; RCD_chk1 = 0; RCD_chk2 = 0; RCD_chk3 = 0; + RC_chk0 = 0; RC_chk1 = 0; RC_chk2 = 0; RC_chk3 = 0; + RP_chk0 = 0; RP_chk1 = 0; RP_chk2 = 0; RP_chk3 = 0; + $timeformat (-9, 1, " ns", 12); + end + + // System clock generator + always begin + @ (posedge Clk) begin + Sys_clk = CkeZ; + CkeZ = Cke; + end + @ (negedge Clk) begin + Sys_clk = 1'b0; + end + end + + // Adjust tAC, tHZ based on CAS Latency + always @ (Cas_latency) begin + case (Cas_latency) + 1 : begin tAC = tAC1; tHZ = tHZ1; end + 2 : begin tAC = tAC2; tHZ = tHZ2; end + 3 : begin tAC = tAC3; tHZ = tHZ3; end + endcase + end + + always @ (posedge Sys_clk) begin + // Internal Commamd Pipelined + Command[0] = Command[1]; + Command[1] = Command[2]; + Command[2] = Command[3]; + Command[3] = `NOP; + + Col_addr[0] = Col_addr[1]; + Col_addr[1] = Col_addr[2]; + Col_addr[2] = Col_addr[3]; + Col_addr[3] = {COL_BITS{1'b0}}; + + Bank_addr[0] = Bank_addr[1]; + Bank_addr[1] = Bank_addr[2]; + Bank_addr[2] = Bank_addr[3]; + Bank_addr[3] = 2'b0; + + Bank_precharge[0] = Bank_precharge[1]; + Bank_precharge[1] = Bank_precharge[2]; + Bank_precharge[2] = Bank_precharge[3]; + Bank_precharge[3] = 2'b0; + + A10_precharge[0] = A10_precharge[1]; + A10_precharge[1] = A10_precharge[2]; + A10_precharge[2] = A10_precharge[3]; + A10_precharge[3] = 1'b0; + + // Dqm pipeline for Read + Dqm_reg0 = Dqm_reg1; + Dqm_reg1 = Dqm; + + // Read or Write with Auto Precharge Counter + if (Auto_precharge[0] === 1'b1) begin + Count_precharge[0] = Count_precharge[0] + 1; + end + if (Auto_precharge[1] === 1'b1) begin + Count_precharge[1] = Count_precharge[1] + 1; + end + if (Auto_precharge[2] === 1'b1) begin + Count_precharge[2] = Count_precharge[2] + 1; + end + if (Auto_precharge[3] === 1'b1) begin + Count_precharge[3] = Count_precharge[3] + 1; + end + + // Read or Write Interrupt Counter + if (RW_interrupt_write[0] === 1'b1) begin + RW_interrupt_counter[0] = RW_interrupt_counter[0] + 1; + end + if (RW_interrupt_write[1] === 1'b1) begin + RW_interrupt_counter[1] = RW_interrupt_counter[1] + 1; + end + if (RW_interrupt_write[2] === 1'b1) begin + RW_interrupt_counter[2] = RW_interrupt_counter[2] + 1; + end + if (RW_interrupt_write[3] === 1'b1) begin + RW_interrupt_counter[3] = RW_interrupt_counter[3] + 1; + end + + // tMRD Counter + MRD_chk = MRD_chk + 1; + + // Auto Refresh + if (Aref_enable === 1'b1) begin + if (Debug) begin + $display ("%m : at time %t AREF : Auto Refresh", $time); + end + + // Auto Refresh to Auto Refresh + if ($time - RFC_chk < tRFC) begin + $display ("%m : at time %t ERROR: tRFC violation during Auto Refresh", $time); + end + + // Precharge to Auto Refresh + if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) || + ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin + $display ("%m : at time %t ERROR: tRP violation during Auto Refresh", $time); + end + + // Precharge to Refresh + if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin + $display ("%m : at time %t ERROR: All banks must be Precharge before Auto Refresh", $time); + end + + // Load Mode Register to Auto Refresh + if (MRD_chk < tMRD) begin + $display ("%m : at time %t ERROR: tMRD violation during Auto Refresh", $time); + end + + // Record Current tRFC time + RFC_chk = $time; + end + + // Load Mode Register + if (Mode_reg_enable === 1'b1) begin + // Register Mode + Mode_reg = Addr; + + // Decode CAS Latency, Burst Length, Burst Type, and Write Burst Mode + if (Debug) begin + $display ("%m : at time %t LMR : Load Mode Register", $time); + // CAS Latency + case (Addr[6 : 4]) + 3'b010 : $display ("%m : CAS Latency = 2"); + 3'b011 : $display ("%m : CAS Latency = 3"); + default : $display ("%m : CAS Latency = Reserved"); + endcase + + // Burst Length + case (Addr[2 : 0]) + 3'b000 : $display ("%m : Burst Length = 1"); + 3'b001 : $display ("%m : Burst Length = 2"); + 3'b010 : $display ("%m : Burst Length = 4"); + 3'b011 : $display ("%m : Burst Length = 8"); + 3'b111 : $display ("%m : Burst Length = Full"); + default : $display ("%m : Burst Length = Reserved"); + endcase + + // Burst Type + if (Addr[3] === 1'b0) begin + $display ("%m : Burst Type = Sequential"); + end else if (Addr[3] === 1'b1) begin + $display ("%m : Burst Type = Interleaved"); + end else begin + $display ("%m : Burst Type = Reserved"); + end + + // Write Burst Mode + if (Addr[9] === 1'b0) begin + $display ("%m : Write Burst Mode = Programmed Burst Length"); + end else if (Addr[9] === 1'b1) begin + $display ("%m : Write Burst Mode = Single Location Access"); + end else begin + $display ("%m : Write Burst Mode = Reserved"); + end + end + + // Precharge to Load Mode Register + if (Pc_b0 === 1'b0 && Pc_b1 === 1'b0 && Pc_b2 === 1'b0 && Pc_b3 === 1'b0) begin + $display ("%m : at time %t ERROR: all banks must be Precharge before Load Mode Register", $time); + end + + // Precharge to Load Mode Register + if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) || + ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin + $display ("%m : at time %t ERROR: tRP violation during Load Mode Register", $time); + end + + // Auto Refresh to Load Mode Register + if ($time - RFC_chk < tRFC) begin + $display ("%m : at time %t ERROR: tRFC violation during Load Mode Register", $time); + end + + // Load Mode Register to Load Mode Register + if (MRD_chk < tMRD) begin + $display ("%m : at time %t ERROR: tMRD violation during Load Mode Register", $time); + end + + // Reset MRD Counter + MRD_chk = 0; + end + + // Active Block (Latch Bank Address and Row Address) + if (Active_enable === 1'b1) begin + // Activate an open bank can corrupt data + if ((Ba === 2'b00 && Act_b0 === 1'b1) || (Ba === 2'b01 && Act_b1 === 1'b1) || + (Ba === 2'b10 && Act_b2 === 1'b1) || (Ba === 2'b11 && Act_b3 === 1'b1)) begin + $display ("%m : at time %t ERROR: Bank already activated -- data can be corrupted", $time); + end + + // Activate Bank 0 + if (Ba === 2'b00 && Pc_b0 === 1'b1) begin + // Debug Message + if (Debug) begin + $display ("%m : at time %t ACT : Bank = 0 Row = %d", $time, Addr); + end + + // ACTIVE to ACTIVE command period + if ($time - RC_chk0 < tRC) begin + $display ("%m : at time %t ERROR: tRC violation during Activate bank 0", $time); + end + + // Precharge to Activate Bank 0 + if ($time - RP_chk0 < tRP) begin + $display ("%m : at time %t ERROR: tRP violation during Activate bank 0", $time); + end + + // Record variables + Act_b0 = 1'b1; + Pc_b0 = 1'b0; + B0_row_addr = Addr [ADDR_BITS - 1 : 0]; + RAS_chk0 = $time; + RC_chk0 = $time; + RCD_chk0 = $time; + end + + if (Ba == 2'b01 && Pc_b1 == 1'b1) begin + // Debug Message + if (Debug) begin + $display ("%m : at time %t ACT : Bank = 1 Row = %d", $time, Addr); + end + + // ACTIVE to ACTIVE command period + if ($time - RC_chk1 < tRC) begin + $display ("%m : at time %t ERROR: tRC violation during Activate bank 1", $time); + end + + // Precharge to Activate Bank 1 + if ($time - RP_chk1 < tRP) begin + $display ("%m : at time %t ERROR: tRP violation during Activate bank 1", $time); + end + + // Record variables + Act_b1 = 1'b1; + Pc_b1 = 1'b0; + B1_row_addr = Addr [ADDR_BITS - 1 : 0]; + RAS_chk1 = $time; + RC_chk1 = $time; + RCD_chk1 = $time; + end + + if (Ba == 2'b10 && Pc_b2 == 1'b1) begin + // Debug Message + if (Debug) begin + $display ("%m : at time %t ACT : Bank = 2 Row = %d", $time, Addr); + end + + // ACTIVE to ACTIVE command period + if ($time - RC_chk2 < tRC) begin + $display ("%m : at time %t ERROR: tRC violation during Activate bank 2", $time); + end + + // Precharge to Activate Bank 2 + if ($time - RP_chk2 < tRP) begin + $display ("%m : at time %t ERROR: tRP violation during Activate bank 2", $time); + end + + // Record variables + Act_b2 = 1'b1; + Pc_b2 = 1'b0; + B2_row_addr = Addr [ADDR_BITS - 1 : 0]; + RAS_chk2 = $time; + RC_chk2 = $time; + RCD_chk2 = $time; + end + + if (Ba == 2'b11 && Pc_b3 == 1'b1) begin + // Debug Message + if (Debug) begin + $display ("%m : at time %t ACT : Bank = 3 Row = %d", $time, Addr); + end + + // ACTIVE to ACTIVE command period + if ($time - RC_chk3 < tRC) begin + $display ("%m : at time %t ERROR: tRC violation during Activate bank 3", $time); + end + + // Precharge to Activate Bank 3 + if ($time - RP_chk3 < tRP) begin + $display ("%m : at time %t ERROR: tRP violation during Activate bank 3", $time); + end + + // Record variables + Act_b3 = 1'b1; + Pc_b3 = 1'b0; + B3_row_addr = Addr [ADDR_BITS - 1 : 0]; + RAS_chk3 = $time; + RC_chk3 = $time; + RCD_chk3 = $time; + end + + // Active Bank A to Active Bank B + if ((Prev_bank != Ba) && ($time - RRD_chk < tRRD)) begin + $display ("%m : at time %t ERROR: tRRD violation during Activate bank = %d", $time, Ba); + end + + // Auto Refresh to Activate + if ($time - RFC_chk < tRFC) begin + $display ("%m : at time %t ERROR: tRFC violation during Activate bank = %d", $time, Ba); + end + + // Load Mode Register to Active + if (MRD_chk < tMRD ) begin + $display ("%m : at time %t ERROR: tMRD violation during Activate bank = %d", $time, Ba); + end + + // Record variables for checking violation + RRD_chk = $time; + Prev_bank = Ba; + end + + // Precharge Block + if (Prech_enable == 1'b1) begin + // Load Mode Register to Precharge + if ($time - MRD_chk < tMRD) begin + $display ("%m : at time %t ERROR: tMRD violaiton during Precharge", $time); + end + + // Precharge Bank 0 + if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b00)) && Act_b0 === 1'b1) begin + Act_b0 = 1'b0; + Pc_b0 = 1'b1; + RP_chk0 = $time; + + // Debug Message + if (Debug) begin + $display ("%m : at time %t PRECHARGE : Bank = 0", $time); + end + + // Activate to Precharge + if ($time - RAS_chk0 < tRAS) begin + $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time); + end + + // tWR violation check for write + if ($time - WR_chkm[0] < tWRm) begin + $display ("%m : at time %t ERROR: tWR violation during Precharge", $time); + end + end + + // Precharge Bank 1 + if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b01)) && Act_b1 === 1'b1) begin + Act_b1 = 1'b0; + Pc_b1 = 1'b1; + RP_chk1 = $time; + + // Debug Message + if (Debug) begin + $display ("%m : at time %t PRECHARGE : Bank = 1", $time); + end + + // Activate to Precharge + if ($time - RAS_chk1 < tRAS) begin + $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time); + end + + // tWR violation check for write + if ($time - WR_chkm[1] < tWRm) begin + $display ("%m : at time %t ERROR: tWR violation during Precharge", $time); + end + end + + // Precharge Bank 2 + if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b10)) && Act_b2 === 1'b1) begin + Act_b2 = 1'b0; + Pc_b2 = 1'b1; + RP_chk2 = $time; + + // Debug Message + if (Debug) begin + $display ("%m : at time %t PRECHARGE : Bank = 2", $time); + end + + // Activate to Precharge + if ($time - RAS_chk2 < tRAS) begin + $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time); + end + + // tWR violation check for write + if ($time - WR_chkm[2] < tWRm) begin + $display ("%m : at time %t ERROR: tWR violation during Precharge", $time); + end + end + + // Precharge Bank 3 + if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b11)) && Act_b3 === 1'b1) begin + Act_b3 = 1'b0; + Pc_b3 = 1'b1; + RP_chk3 = $time; + + // Debug Message + if (Debug) begin + $display ("%m : at time %t PRECHARGE : Bank = 3", $time); + end + + // Activate to Precharge + if ($time - RAS_chk3 < tRAS) begin + $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time); + end + + // tWR violation check for write + if ($time - WR_chkm[3] < tWRm) begin + $display ("%m : at time %t ERROR: tWR violation during Precharge", $time); + end + end + + // Precharge truncation with DQM set + if ((Data_in_enable == 1'b1) && ~(&Dqm)) begin + $display ("%m : at time %t ERROR: DQM not asserted during Precharge truncation", $time); + end + + // Terminate a Write Immediately (if same bank or all banks) + if (Data_in_enable === 1'b1 && (Bank === Ba || Addr[10] === 1'b1)) begin + Data_in_enable = 1'b0; + end + + // Precharge Command Pipeline for Read + Command[Cas_latency - 1] = `PRECH; + Bank_precharge[Cas_latency - 1] = Ba; + A10_precharge[Cas_latency - 1] = Addr[10]; + end + + // Burst terminate + if (Burst_term === 1'b1) begin + // Terminate a Write Immediately + if (Data_in_enable == 1'b1) begin + Data_in_enable = 1'b0; + end + + // Terminate a Read Depend on CAS Latency + Command[Cas_latency - 1] = `BST; + + // Display debug message + if (Debug) begin + $display ("%m : at time %t BST : Burst Terminate",$time); + end + end + + // Read, Write, Column Latch + if (Read_enable === 1'b1) begin + // Check to see if bank is open (ACT) + if ((Ba == 2'b00 && Pc_b0 == 1'b1) || (Ba == 2'b01 && Pc_b1 == 1'b1) || + (Ba == 2'b10 && Pc_b2 == 1'b1) || (Ba == 2'b11 && Pc_b3 == 1'b1)) begin + $display("%m : at time %t ERROR: Bank is not Activated for Read", $time); + end + + // Activate to Read or Write + if ((Ba == 2'b00) && ($time - RCD_chk0 < tRCD) || + (Ba == 2'b01) && ($time - RCD_chk1 < tRCD) || + (Ba == 2'b10) && ($time - RCD_chk2 < tRCD) || + (Ba == 2'b11) && ($time - RCD_chk3 < tRCD)) begin + $display("%m : at time %t ERROR: tRCD violation during Read", $time); + end + + // CAS Latency pipeline + Command[Cas_latency - 1] = `READ; + Col_addr[Cas_latency - 1] = Addr; + Bank_addr[Cas_latency - 1] = Ba; + + // Read interrupt Write (terminate Write immediately) + if (Data_in_enable == 1'b1) begin + Data_in_enable = 1'b0; + + // Interrupting a Write with Autoprecharge + if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Write_precharge[RW_interrupt_bank] == 1'b1) begin + RW_interrupt_write[RW_interrupt_bank] = 1'b1; + RW_interrupt_counter[RW_interrupt_bank] = 0; + + // Display debug message + if (Debug) begin + $display ("%m : at time %t NOTE : Read interrupt Write with Autoprecharge", $time); + end + end + end + + // Read with Auto Precharge + if (Addr[10] == 1'b1) begin + Auto_precharge[Ba] = 1'b1; + Count_precharge[Ba] = 0; + RW_interrupt_bank = Ba; + Read_precharge[Ba] = 1'b1; + end + end + + // Write Command + if (Write_enable == 1'b1) begin + // Activate to Write + if ((Ba == 2'b00 && Pc_b0 == 1'b1) || (Ba == 2'b01 && Pc_b1 == 1'b1) || + (Ba == 2'b10 && Pc_b2 == 1'b1) || (Ba == 2'b11 && Pc_b3 == 1'b1)) begin + $display("%m : at time %t ERROR: Bank is not Activated for Write", $time); + end + + // Activate to Read or Write + if ((Ba == 2'b00) && ($time - RCD_chk0 < tRCD) || + (Ba == 2'b01) && ($time - RCD_chk1 < tRCD) || + (Ba == 2'b10) && ($time - RCD_chk2 < tRCD) || + (Ba == 2'b11) && ($time - RCD_chk3 < tRCD)) begin + $display("%m : at time %t ERROR: tRCD violation during Read", $time); + end + + // Latch Write command, Bank, and Column + Command[0] = `WRITE; + Col_addr[0] = Addr; + Bank_addr[0] = Ba; + + // Write interrupt Write (terminate Write immediately) + if (Data_in_enable == 1'b1) begin + Data_in_enable = 1'b0; + + // Interrupting a Write with Autoprecharge + if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Write_precharge[RW_interrupt_bank] == 1'b1) begin + RW_interrupt_write[RW_interrupt_bank] = 1'b1; + + // Display debug message + if (Debug) begin + $display ("%m : at time %t NOTE : Read Bank %d interrupt Write Bank %d with Autoprecharge", $time, Ba, RW_interrupt_bank); + end + end + end + + // Write interrupt Read (terminate Read immediately) + if (Data_out_enable == 1'b1) begin + Data_out_enable = 1'b0; + + // Interrupting a Read with Autoprecharge + if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Read_precharge[RW_interrupt_bank] == 1'b1) begin + RW_interrupt_read[RW_interrupt_bank] = 1'b1; + + // Display debug message + if (Debug) begin + $display ("%m : at time %t NOTE : Write Bank %d interrupt Read Bank %d with Autoprecharge", $time, Ba, RW_interrupt_bank); + end + end + end + + // Write with Auto Precharge + if (Addr[10] == 1'b1) begin + Auto_precharge[Ba] = 1'b1; + Count_precharge[Ba] = 0; + RW_interrupt_bank = Ba; + Write_precharge[Ba] = 1'b1; + end + end + + /* + Write with Auto Precharge Calculation + The device start internal precharge when: + 1. Meet minimum tRAS requirement + and 2. tWR cycle(s) after last valid data + or 3. Interrupt by a Read or Write (with or without Auto Precharge) + + Note: Model is starting the internal precharge 1 cycle after they meet all the + requirement but tRP will be compensate for the time after the 1 cycle. + */ + if ((Auto_precharge[0] == 1'b1) && (Write_precharge[0] == 1'b1)) begin + if ((($time - RAS_chk0 >= tRAS) && // Case 1 + (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [0] >= 1) || // Case 2 + (Burst_length_2 == 1'b1 && Count_precharge [0] >= 2) || + (Burst_length_4 == 1'b1 && Count_precharge [0] >= 4) || + (Burst_length_8 == 1'b1 && Count_precharge [0] >= 8))) || + (RW_interrupt_write[0] == 1'b1 && RW_interrupt_counter[0] >= 1)) begin // Case 3 + Auto_precharge[0] = 1'b0; + Write_precharge[0] = 1'b0; + RW_interrupt_write[0] = 1'b0; + Pc_b0 = 1'b1; + Act_b0 = 1'b0; + RP_chk0 = $time + tWRa; + if (Debug) begin + $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time); + end + end + end + if ((Auto_precharge[1] == 1'b1) && (Write_precharge[1] == 1'b1)) begin + if ((($time - RAS_chk1 >= tRAS) && // Case 1 + (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [1] >= 1) || // Case 2 + (Burst_length_2 == 1'b1 && Count_precharge [1] >= 2) || + (Burst_length_4 == 1'b1 && Count_precharge [1] >= 4) || + (Burst_length_8 == 1'b1 && Count_precharge [1] >= 8))) || + (RW_interrupt_write[1] == 1'b1 && RW_interrupt_counter[1] >= 1)) begin // Case 3 + Auto_precharge[1] = 1'b0; + Write_precharge[1] = 1'b0; + RW_interrupt_write[1] = 1'b0; + Pc_b1 = 1'b1; + Act_b1 = 1'b0; + RP_chk1 = $time + tWRa; + if (Debug) begin + $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time); + end + end + end + if ((Auto_precharge[2] == 1'b1) && (Write_precharge[2] == 1'b1)) begin + if ((($time - RAS_chk2 >= tRAS) && // Case 1 + (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [2] >= 1) || // Case 2 + (Burst_length_2 == 1'b1 && Count_precharge [2] >= 2) || + (Burst_length_4 == 1'b1 && Count_precharge [2] >= 4) || + (Burst_length_8 == 1'b1 && Count_precharge [2] >= 8))) || + (RW_interrupt_write[2] == 1'b1 && RW_interrupt_counter[2] >= 1)) begin // Case 3 + Auto_precharge[2] = 1'b0; + Write_precharge[2] = 1'b0; + RW_interrupt_write[2] = 1'b0; + Pc_b2 = 1'b1; + Act_b2 = 1'b0; + RP_chk2 = $time + tWRa; + if (Debug) begin + $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time); + end + end + end + if ((Auto_precharge[3] == 1'b1) && (Write_precharge[3] == 1'b1)) begin + if ((($time - RAS_chk3 >= tRAS) && // Case 1 + (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [3] >= 1) || // Case 2 + (Burst_length_2 == 1'b1 && Count_precharge [3] >= 2) || + (Burst_length_4 == 1'b1 && Count_precharge [3] >= 4) || + (Burst_length_8 == 1'b1 && Count_precharge [3] >= 8))) || + (RW_interrupt_write[3] == 1'b1 && RW_interrupt_counter[3] >= 1)) begin // Case 3 + Auto_precharge[3] = 1'b0; + Write_precharge[3] = 1'b0; + RW_interrupt_write[3] = 1'b0; + Pc_b3 = 1'b1; + Act_b3 = 1'b0; + RP_chk3 = $time + tWRa; + if (Debug) begin + $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time); + end + end + end + + // Read with Auto Precharge Calculation + // The device start internal precharge: + // 1. Meet minimum tRAS requirement + // and 2. CAS Latency - 1 cycles before last burst + // or 3. Interrupt by a Read or Write (with or without AutoPrecharge) + if ((Auto_precharge[0] == 1'b1) && (Read_precharge[0] == 1'b1)) begin + if ((($time - RAS_chk0 >= tRAS) && // Case 1 + ((Burst_length_1 == 1'b1 && Count_precharge[0] >= 1) || // Case 2 + (Burst_length_2 == 1'b1 && Count_precharge[0] >= 2) || + (Burst_length_4 == 1'b1 && Count_precharge[0] >= 4) || + (Burst_length_8 == 1'b1 && Count_precharge[0] >= 8))) || + (RW_interrupt_read[0] == 1'b1)) begin // Case 3 + Pc_b0 = 1'b1; + Act_b0 = 1'b0; + RP_chk0 = $time; + Auto_precharge[0] = 1'b0; + Read_precharge[0] = 1'b0; + RW_interrupt_read[0] = 1'b0; + if (Debug) begin + $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time); + end + end + end + if ((Auto_precharge[1] == 1'b1) && (Read_precharge[1] == 1'b1)) begin + if ((($time - RAS_chk1 >= tRAS) && + ((Burst_length_1 == 1'b1 && Count_precharge[1] >= 1) || + (Burst_length_2 == 1'b1 && Count_precharge[1] >= 2) || + (Burst_length_4 == 1'b1 && Count_precharge[1] >= 4) || + (Burst_length_8 == 1'b1 && Count_precharge[1] >= 8))) || + (RW_interrupt_read[1] == 1'b1)) begin + Pc_b1 = 1'b1; + Act_b1 = 1'b0; + RP_chk1 = $time; + Auto_precharge[1] = 1'b0; + Read_precharge[1] = 1'b0; + RW_interrupt_read[1] = 1'b0; + if (Debug) begin + $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time); + end + end + end + if ((Auto_precharge[2] == 1'b1) && (Read_precharge[2] == 1'b1)) begin + if ((($time - RAS_chk2 >= tRAS) && + ((Burst_length_1 == 1'b1 && Count_precharge[2] >= 1) || + (Burst_length_2 == 1'b1 && Count_precharge[2] >= 2) || + (Burst_length_4 == 1'b1 && Count_precharge[2] >= 4) || + (Burst_length_8 == 1'b1 && Count_precharge[2] >= 8))) || + (RW_interrupt_read[2] == 1'b1)) begin + Pc_b2 = 1'b1; + Act_b2 = 1'b0; + RP_chk2 = $time; + Auto_precharge[2] = 1'b0; + Read_precharge[2] = 1'b0; + RW_interrupt_read[2] = 1'b0; + if (Debug) begin + $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time); + end + end + end + if ((Auto_precharge[3] == 1'b1) && (Read_precharge[3] == 1'b1)) begin + if ((($time - RAS_chk3 >= tRAS) && + ((Burst_length_1 == 1'b1 && Count_precharge[3] >= 1) || + (Burst_length_2 == 1'b1 && Count_precharge[3] >= 2) || + (Burst_length_4 == 1'b1 && Count_precharge[3] >= 4) || + (Burst_length_8 == 1'b1 && Count_precharge[3] >= 8))) || + (RW_interrupt_read[3] == 1'b1)) begin + Pc_b3 = 1'b1; + Act_b3 = 1'b0; + RP_chk3 = $time; + Auto_precharge[3] = 1'b0; + Read_precharge[3] = 1'b0; + RW_interrupt_read[3] = 1'b0; + if (Debug) begin + $display("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time); + end + end + end + + // Internal Precharge or Bst + if (Command[0] == `PRECH) begin // Precharge terminate a read with same bank or all banks + if (Bank_precharge[0] == Bank || A10_precharge[0] == 1'b1) begin + if (Data_out_enable == 1'b1) begin + Data_out_enable = 1'b0; + end + end + end else if (Command[0] == `BST) begin // BST terminate a read to current bank + if (Data_out_enable == 1'b1) begin + Data_out_enable = 1'b0; + end + end + + if (Data_out_enable == 1'b0) begin + Dq_reg <= #tOH {DQ_BITS{1'bz}}; + end + + // Detect Read or Write command + if (Command[0] == `READ) begin + Bank = Bank_addr[0]; + Col = Col_addr[0]; + Col_brst = Col_addr[0]; + case (Bank_addr[0]) + 2'b00 : Row = B0_row_addr; + 2'b01 : Row = B1_row_addr; + 2'b10 : Row = B2_row_addr; + 2'b11 : Row = B3_row_addr; + endcase + Burst_counter = 0; + Data_in_enable = 1'b0; + Data_out_enable = 1'b1; + end else if (Command[0] == `WRITE) begin + Bank = Bank_addr[0]; + Col = Col_addr[0]; + Col_brst = Col_addr[0]; + case (Bank_addr[0]) + 2'b00 : Row = B0_row_addr; + 2'b01 : Row = B1_row_addr; + 2'b10 : Row = B2_row_addr; + 2'b11 : Row = B3_row_addr; + endcase + Burst_counter = 0; + Data_in_enable = 1'b1; + Data_out_enable = 1'b0; + end + + // DQ buffer (Driver/Receiver) + if (Data_in_enable == 1'b1) begin // Writing Data to Memory + // Array buffer + case (Bank) + 2'b00 : Dq_dqm = Bank0 [{Row, Col}]; + 2'b01 : Dq_dqm = Bank1 [{Row, Col}]; + 2'b10 : Dq_dqm = Bank2 [{Row, Col}]; + 2'b11 : Dq_dqm = Bank3 [{Row, Col}]; + endcase + + // Dqm operation +`ifdef x4 + if (Dqm[0] == 1'b0) begin + Dq_dqm [ 3 : 0] = Dq [ 3 : 0]; + end +`elsif x8 + if (Dqm[0] == 1'b0) begin + Dq_dqm [ 7 : 0] = Dq [ 7 : 0]; + end +`elsif x16 + if (Dqm[0] == 1'b0) begin + Dq_dqm [ 7 : 0] = Dq [ 7 : 0]; + end + if (Dqm[1] == 1'b0) begin + Dq_dqm [15 : 8] = Dq [15 : 8]; + end +`endif + + // Write to memory + case (Bank) + 2'b00 : Bank0 [{Row, Col}] = Dq_dqm; + 2'b01 : Bank1 [{Row, Col}] = Dq_dqm; + 2'b10 : Bank2 [{Row, Col}] = Dq_dqm; + 2'b11 : Bank3 [{Row, Col}] = Dq_dqm; + endcase + + // Display debug message + if (Dqm !== 2'b11) begin + // Record tWR for manual precharge + WR_chkm [Bank] = $time; + + if (Debug) begin + $display("%m : at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = %h", $time, Bank, Row, Col, Dq_dqm); + end + end else begin + if (Debug) begin + $display("%m : at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $time, Bank, Row, Col); + end + end + + // Advance burst counter subroutine + #tHZ Burst_decode; + + end else if (Data_out_enable == 1'b1) begin // Reading Data from Memory + // Array buffer + case (Bank) + 2'b00 : Dq_dqm = Bank0[{Row, Col}]; + 2'b01 : Dq_dqm = Bank1[{Row, Col}]; + 2'b10 : Dq_dqm = Bank2[{Row, Col}]; + 2'b11 : Dq_dqm = Bank3[{Row, Col}]; + endcase + + // Dqm operation +`ifdef x4 + if (Dqm_reg0 [0] == 1'b1) begin + Dq_dqm [ 3 : 0] = 4'bz; + end +`elsif x8 + if (Dqm_reg0 [0] == 1'b1) begin + Dq_dqm [ 7 : 0] = 8'bz; + end +`elsif x16 + if (Dqm_reg0 [0] == 1'b1) begin + Dq_dqm [ 7 : 0] = 8'bz; + end + if (Dqm_reg0 [1] == 1'b1) begin + Dq_dqm [15 : 8] = 8'bz; + end +`endif + + // Display debug message + Dq_reg = #tAC Dq_dqm; + if (Debug) begin + $display("%m : at time %t READ : Bank = %d Row = %d, Col = %d, Dqm = %b, Data = %h", $time, Bank, Row, Col, Dqm_reg0, Dq_reg); + end + + // Advance burst counter subroutine + Burst_decode; + end + end + + // Burst counter decode + task Burst_decode; + begin + // Advance Burst Counter + Burst_counter = Burst_counter + 1; + + // Burst Type + if (Mode_reg[3] == 1'b0) begin // Sequential Burst + Col_temp = Col + 1; + end else if (Mode_reg[3] == 1'b1) begin // Interleaved Burst + Col_temp[2] = Burst_counter[2] ^ Col_brst[2]; + Col_temp[1] = Burst_counter[1] ^ Col_brst[1]; + Col_temp[0] = Burst_counter[0] ^ Col_brst[0]; + end + + // Burst Length + if (Burst_length_2) begin // Burst Length = 2 + Col [0] = Col_temp [0]; + end else if (Burst_length_4) begin // Burst Length = 4 + Col [1 : 0] = Col_temp [1 : 0]; + end else if (Burst_length_8) begin // Burst Length = 8 + Col [2 : 0] = Col_temp [2 : 0]; + end else begin // Burst Length = FULL + Col = Col_temp; + end + + // Burst Read Single Write + if (Write_burst_mode == 1'b1) begin + Data_in_enable = 1'b0; + end + + // Data Counter + if (Burst_length_1 == 1'b1) begin + if (Burst_counter >= 1) begin + Data_in_enable = 1'b0; + Data_out_enable = 1'b0; + end + end else if (Burst_length_2 == 1'b1) begin + if (Burst_counter >= 2) begin + Data_in_enable = 1'b0; + Data_out_enable = 1'b0; + end + end else if (Burst_length_4 == 1'b1) begin + if (Burst_counter >= 4) begin + Data_in_enable = 1'b0; + Data_out_enable = 1'b0; + end + end else if (Burst_length_8 == 1'b1) begin + if (Burst_counter >= 8) begin + Data_in_enable = 1'b0; + Data_out_enable = 1'b0; + end + end + end + endtask + + // Timing Parameters for -75 (133 MHz @ CL3) + specify + specparam + tAH = 0.8, // Addr, Ba Hold Time + tAS = 1.5, // Addr, Ba Setup Time + `ifdef CLK_166 + tCK3 = 6, + `elsif CLK_133 + tCK3 = 7.5, + `elsif CLK_100 + tCK3 = 10, + `elsif CLK_200 + tCK3 = 5, + `endif + tCH = 2.5, // Clock High-Level Width + tCL = 2.5, // Clock Low-Level Width + tCKH = 0.8, // CKE Hold Time + tCKS = 1.5, // CKE Setup Time + tCMH = 0.8, // CS#, RAS#, CAS#, WE#, DQM# Hold Time + tCMS = 1.5, // CS#, RAS#, CAS#, WE#, DQM# Setup Time + tDH = 0.8, // Data-in Hold Time + tDS = 1.5; // Data-in Setup Time + $width (posedge Clk, tCH); + $width (negedge Clk, tCL); + $period (negedge Clk, tCK3); + $period (posedge Clk, tCK3); + $setuphold(posedge Clk, Cke, tCKS, tCKH); + $setuphold(posedge Clk, Cs_n, tCMS, tCMH); + $setuphold(posedge Clk, Cas_n, tCMS, tCMH); + $setuphold(posedge Clk, Ras_n, tCMS, tCMH); + $setuphold(posedge Clk, We_n, tCMS, tCMH); + $setuphold(posedge Clk, Addr, tAS, tAH); + $setuphold(posedge Clk, Ba, tAS, tAH); + $setuphold(posedge Clk, Dqm, tCMS, tCMH); + $setuphold(posedge Dq_chk, Dq, tDS, tDH); + endspecify + +endmodule diff --git a/hw/efinix_fpga/simulation/super6502_sdram_controller_define.vh b/hw/efinix_fpga/simulation/super6502_sdram_controller_define.vh new file mode 100644 index 0000000..a36208b --- /dev/null +++ b/hw/efinix_fpga/simulation/super6502_sdram_controller_define.vh @@ -0,0 +1,23 @@ + +localparam fSYS_MHz = 100; +localparam fCK_MHz = 200; +localparam tIORT_u = 2; +localparam BL = 1; +localparam DDIO_TYPE = "SOFT"; +localparam DQ_WIDTH = 8; +localparam DQ_GROUP = 4; +localparam BA_WIDTH = 2; +localparam ROW_WIDTH = 13; +localparam COL_WIDTH = 10; +localparam tPWRUP = 200000; +localparam tRAS = 44; +localparam tRC = 66; +localparam tRCD = 20; +localparam tREF = 64000000; +localparam tWR = 2; +localparam tMRD = 2; +localparam tRFC = 66; +localparam tRAS_MAX = 120000; +localparam DATA_RATE = 2; +localparam tRP = 20; +localparam CL = 3; From 1f503b2d8018f758bb37f5789b1becc9092d16af Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Thu, 21 Sep 2023 20:35:52 -0700 Subject: [PATCH 03/57] update sim environment --- hw/efinix_fpga/simulation/Makefile | 23 +- .../super6502_sdram_controller_define.vh | 4 +- .../simulation/interrupt_controller_tb.sv | 76 - .../simulation/spi_controller_tb.sv | 102 -- .../simulation/{ => src}/generic_sdr.v | 2 +- .../simulation/{ => src}/sim_top.sv | 2 - .../simulation/src/verilog-6502/ALU.v | 108 ++ .../simulation/src/verilog-6502/README.md | 69 + .../simulation/src/verilog-6502/cpu.v | 1220 ++++++++++++++ .../simulation/src/verilog-6502/cpu_65c02.v | 1418 +++++++++++++++++ hw/efinix_fpga/simulation/timer_tb.sv | 75 - hw/efinix_fpga/simulation/verilog-6502 | 1 - hw/efinix_fpga/src/sdram_adapter.sv | 5 +- 13 files changed, 2831 insertions(+), 274 deletions(-) rename hw/efinix_fpga/simulation/{ => include}/super6502_sdram_controller_define.vh (90%) delete mode 100644 hw/efinix_fpga/simulation/interrupt_controller_tb.sv delete mode 100644 hw/efinix_fpga/simulation/spi_controller_tb.sv rename hw/efinix_fpga/simulation/{ => src}/generic_sdr.v (97%) rename hw/efinix_fpga/simulation/{ => src}/sim_top.sv (68%) create mode 100755 hw/efinix_fpga/simulation/src/verilog-6502/ALU.v create mode 100644 hw/efinix_fpga/simulation/src/verilog-6502/README.md create mode 100644 hw/efinix_fpga/simulation/src/verilog-6502/cpu.v create mode 100644 hw/efinix_fpga/simulation/src/verilog-6502/cpu_65c02.v delete mode 100644 hw/efinix_fpga/simulation/timer_tb.sv delete mode 160000 hw/efinix_fpga/simulation/verilog-6502 diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index c3b0f2e..bd842ad 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -1,20 +1,17 @@ -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 +#TODO implement something like sources.list -spi_controller: spi_controller_tb.sv ../spi_controller.sv - iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv +TOP_MODULE=sim_top +TARGET=sim_top -interrupt_controller: interrupt_controller_tb.sv - iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv +all: + iverilog -g2005-sv -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS) .PHONY: clean - clean: - rm -f $(TARGETS) - rm -f *.vcd - rm -f *.vvp \ No newline at end of file + rm -rf $(TARGET) \ No newline at end of file diff --git a/hw/efinix_fpga/simulation/super6502_sdram_controller_define.vh b/hw/efinix_fpga/simulation/include/super6502_sdram_controller_define.vh similarity index 90% rename from hw/efinix_fpga/simulation/super6502_sdram_controller_define.vh rename to hw/efinix_fpga/simulation/include/super6502_sdram_controller_define.vh index a36208b..077f158 100644 --- a/hw/efinix_fpga/simulation/super6502_sdram_controller_define.vh +++ b/hw/efinix_fpga/simulation/include/super6502_sdram_controller_define.vh @@ -5,10 +5,10 @@ localparam tIORT_u = 2; localparam BL = 1; localparam DDIO_TYPE = "SOFT"; localparam DQ_WIDTH = 8; -localparam DQ_GROUP = 4; +localparam DQ_GROUP = 2; localparam BA_WIDTH = 2; localparam ROW_WIDTH = 13; -localparam COL_WIDTH = 10; +localparam COL_WIDTH = 9; localparam tPWRUP = 200000; localparam tRAS = 44; localparam tRC = 66; diff --git a/hw/efinix_fpga/simulation/interrupt_controller_tb.sv b/hw/efinix_fpga/simulation/interrupt_controller_tb.sv deleted file mode 100644 index 7cd41e8..0000000 --- a/hw/efinix_fpga/simulation/interrupt_controller_tb.sv +++ /dev/null @@ -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 diff --git a/hw/efinix_fpga/simulation/spi_controller_tb.sv b/hw/efinix_fpga/simulation/spi_controller_tb.sv deleted file mode 100644 index ad20da4..0000000 --- a/hw/efinix_fpga/simulation/spi_controller_tb.sv +++ /dev/null @@ -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 diff --git a/hw/efinix_fpga/simulation/generic_sdr.v b/hw/efinix_fpga/simulation/src/generic_sdr.v similarity index 97% rename from hw/efinix_fpga/simulation/generic_sdr.v rename to hw/efinix_fpga/simulation/src/generic_sdr.v index 912d519..06eaa99 100644 --- a/hw/efinix_fpga/simulation/generic_sdr.v +++ b/hw/efinix_fpga/simulation/src/generic_sdr.v @@ -49,7 +49,7 @@ module generic_sdr (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm); -`include "super6502_sdram_controller_define.vh" +`include "include/super6502_sdram_controller_define.vh" parameter tCK = 1000/fCK_MHz; // tCK ns Nominal Clock Cycle Time `ifdef CLK_200 diff --git a/hw/efinix_fpga/simulation/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv similarity index 68% rename from hw/efinix_fpga/simulation/sim_top.sv rename to hw/efinix_fpga/simulation/src/sim_top.sv index 81ceefc..c20fa0f 100644 --- a/hw/efinix_fpga/simulation/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -6,7 +6,5 @@ cpu_65c02 u_cpu(); //TODO: also this super6502 u_dut(); -//TODO: decide what to do here -memory u_mem(); endmodule \ No newline at end of file diff --git a/hw/efinix_fpga/simulation/src/verilog-6502/ALU.v b/hw/efinix_fpga/simulation/src/verilog-6502/ALU.v new file mode 100755 index 0000000..8d05fc0 --- /dev/null +++ b/hw/efinix_fpga/simulation/src/verilog-6502/ALU.v @@ -0,0 +1,108 @@ +/* + * ALU. + * + * AI and BI are 8 bit inputs. Result in OUT. + * CI is Carry In. + * CO is Carry Out. + * + * op[3:0] is defined as follows: + * + * 0011 AI + BI + * 0111 AI - BI + * 1011 AI + AI + * 1100 AI | BI + * 1101 AI & BI + * 1110 AI ^ BI + * 1111 AI + * + */ + +module ALU( clk, op, right, AI, BI, CI, CO, BCD, OUT, V, Z, N, HC, RDY ); + input clk; + input right; + input [3:0] op; // operation + input [7:0] AI; + input [7:0] BI; + input CI; + input BCD; // BCD style carry + output [7:0] OUT; + output CO; + output V; + output Z; + output N; + output HC; + input RDY; + +reg [7:0] OUT; +reg CO; +wire V; +wire Z; +reg N; +reg HC; + +reg AI7; +reg BI7; +reg [8:0] temp_logic; +reg [7:0] temp_BI; +reg [4:0] temp_l; +reg [4:0] temp_h; +wire [8:0] temp = { temp_h, temp_l[3:0] }; +wire adder_CI = (right | (op[3:2] == 2'b11)) ? 0 : CI; + +// calculate the logic operations. The 'case' can be done in 1 LUT per +// bit. The 'right' shift is a simple mux that can be implemented by +// F5MUX. +always @* begin + case( op[1:0] ) + 2'b00: temp_logic = AI | BI; + 2'b01: temp_logic = AI & BI; + 2'b10: temp_logic = AI ^ BI; + 2'b11: temp_logic = AI; + endcase + + if( right ) + temp_logic = { AI[0], CI, AI[7:1] }; +end + +// Add logic result to BI input. This only makes sense when logic = AI. +// This stage can be done in 1 LUT per bit, using carry chain logic. +always @* begin + case( op[3:2] ) + 2'b00: temp_BI = BI; // A+B + 2'b01: temp_BI = ~BI; // A-B + 2'b10: temp_BI = temp_logic; // A+A + 2'b11: temp_BI = 0; // A+0 + endcase +end + +// HC9 is the half carry bit when doing BCD add +wire HC9 = BCD & (temp_l[3:1] >= 3'd5); + +// CO9 is the carry-out bit when doing BCD add +wire CO9 = BCD & (temp_h[3:1] >= 3'd5); + +// combined half carry bit +wire temp_HC = temp_l[4] | HC9; + +// perform the addition as 2 separate nibble, so we get +// access to the half carry flag +always @* begin + temp_l = temp_logic[3:0] + temp_BI[3:0] + adder_CI; + temp_h = temp_logic[8:4] + temp_BI[7:4] + temp_HC; +end + +// calculate the flags +always @(posedge clk) + if( RDY ) begin + AI7 <= AI[7]; + BI7 <= temp_BI[7]; + OUT <= temp[7:0]; + CO <= temp[8] | CO9; + N <= temp[7]; + HC <= temp_HC; + end + +assign V = AI7 ^ BI7 ^ CO ^ N; +assign Z = ~|OUT; + +endmodule diff --git a/hw/efinix_fpga/simulation/src/verilog-6502/README.md b/hw/efinix_fpga/simulation/src/verilog-6502/README.md new file mode 100644 index 0000000..42e6ad6 --- /dev/null +++ b/hw/efinix_fpga/simulation/src/verilog-6502/README.md @@ -0,0 +1,69 @@ +======================================================== +A Verilog HDL version of the old MOS 6502 and 65C02 CPUs +======================================================== + +Original 6502 core by Arlet Ottens + +65C02 extensions by David Banks and Ed Spittles + +========== +6502 Core +========== + +Arlet's original 6502 core (cpu.v) is unchanged. + +Note: the 6502/65C02 cores assumes a synchronous memory. This means +that valid data (DI) is expected on the cycle *after* valid +address. This allows direct connection to (Xilinx) block RAMs. When +using asynchronous memory, I suggest registering the address/control +lines for glitchless output signals. + +[Also check out my new 65C02 project](https://github.com/Arlet/verilog-65c02) + +Have fun. + +========== +65C02 Core +========== + +A second core (cpu_65c02.v) has been added, based on Arlet's 6502 +core, with additional 65C02 instructions and addressing modes: +- PHX, PHY, PLX, PLY +- BRA +- INC A, DEC A +- (zp) addressing mode +- STZ +- BIT zpx, absx, imm +- TSB/TRB +- JMP (,X) +- NOPs (optional) +- 65C02 BCD N/Z flags (optional, disabled) + +The Rockwell/WDC specific instructions (RMB/SMB/BBR/BBS/WAI/STP) are +not currently implemented + +The 65C02 core passes the Dormann 6502 test suite, and also passes the +Dormann 65C02 test suite if the optional support for NOPs and 65C02 +BCD flags is enabled. + +It has been tested as a BBC Micro "Matchbox" 65C02 Co Processor, in a +XC6SLX9-2 FPGA, running at 80MHz using 64KB of internel block RAM. It +just meets timing at 80MHz in this environment. It successfully runs +BBC Basic IV and Tube Elite. + +============ +Known Issues +============ + +The Matchbox Co Processor needed one wait state (via RDY) to be added +to each ROM access (only needed early in the boot process, as +eventually everything runs from RAM). The DIHOLD logic did not work +correctly with a single wait state, and so has been commented out. + +I now believe the correct fix is actually just: + +always @(posedge clk ) + if( RDY ) + DIHOLD <= DI; + +assign DIMUX = ~RDY ? DIHOLD : DI; diff --git a/hw/efinix_fpga/simulation/src/verilog-6502/cpu.v b/hw/efinix_fpga/simulation/src/verilog-6502/cpu.v new file mode 100644 index 0000000..ed8da62 --- /dev/null +++ b/hw/efinix_fpga/simulation/src/verilog-6502/cpu.v @@ -0,0 +1,1220 @@ +/* + * verilog model of 6502 CPU. + * + * (C) Arlet Ottens, + * + * Feel free to use this code in any project (commercial or not), as long as you + * keep this message, and the copyright notice. This code is provided "as is", + * without any warranties of any kind. + * + */ + +/* + * Note that not all 6502 interface signals are supported (yet). The goal + * is to create an Acorn Atom model, and the Atom didn't use all signals on + * the main board. + * + * The data bus is implemented as separate read/write buses. Combine them + * on the output pads if external memory is required. + */ + +module cpu( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY ); + +input clk; // CPU clock +input reset; // reset signal +output reg [15:0] AB; // address bus +input [7:0] DI; // data in, read bus +output [7:0] DO; // data out, write bus +output WE; // write enable +input IRQ; // interrupt request +input NMI; // non-maskable interrupt request +input RDY; // Ready signal. Pauses CPU when RDY=0 + +/* + * internal signals + */ + +reg [15:0] PC; // Program Counter +reg [7:0] ABL; // Address Bus Register LSB +reg [7:0] ABH; // Address Bus Register MSB +wire [7:0] ADD; // Adder Hold Register (registered in ALU) + +reg [7:0] DIHOLD; // Hold for Data In +reg DIHOLD_valid; // +wire [7:0] DIMUX; // + +reg [7:0] IRHOLD; // Hold for Instruction register +reg IRHOLD_valid; // Valid instruction in IRHOLD + +reg [7:0] AXYS[3:0]; // A, X, Y and S register file + +reg C = 0; // carry flag (init at zero to avoid X's in ALU sim) +reg Z = 0; // zero flag +reg I = 0; // interrupt flag +reg D = 0; // decimal flag +reg V = 0; // overflow flag +reg N = 0; // negative flag +wire AZ; // ALU Zero flag +wire AV; // ALU overflow flag +wire AN; // ALU negative flag +wire HC; // ALU half carry + +reg [7:0] AI; // ALU Input A +reg [7:0] BI; // ALU Input B +wire [7:0] DI; // Data In +wire [7:0] IR; // Instruction register +reg [7:0] DO; // Data Out +reg WE; // Write Enable +reg CI; // Carry In +wire CO; // Carry Out +wire [7:0] PCH = PC[15:8]; +wire [7:0] PCL = PC[7:0]; + +reg NMI_edge = 0; // captured NMI edge + +reg [1:0] regsel; // Select A, X, Y or S register +wire [7:0] regfile = AXYS[regsel]; // Selected register output + +parameter + SEL_A = 2'd0, + SEL_S = 2'd1, + SEL_X = 2'd2, + SEL_Y = 2'd3; + +/* + * define some signals for watching in simulator output + */ + + +`ifdef SIM +wire [7:0] A = AXYS[SEL_A]; // Accumulator +wire [7:0] X = AXYS[SEL_X]; // X register +wire [7:0] Y = AXYS[SEL_Y]; // Y register +wire [7:0] S = AXYS[SEL_S]; // Stack pointer +`endif + +wire [7:0] P = { N, V, 2'b11, D, I, Z, C }; + +/* + * instruction decoder/sequencer + */ + +reg [5:0] state; + +/* + * control signals + */ + +reg PC_inc; // Increment PC +reg [15:0] PC_temp; // intermediate value of PC + +reg [1:0] src_reg; // source register index +reg [1:0] dst_reg; // destination register index + +reg index_y; // if set, then Y is index reg rather than X +reg load_reg; // loading a register (A, X, Y, S) in this instruction +reg inc; // increment +reg write_back; // set if memory is read/modified/written +reg load_only; // LDA/LDX/LDY instruction +reg store; // doing store (STA/STX/STY) +reg adc_sbc; // doing ADC/SBC +reg compare; // doing CMP/CPY/CPX +reg shift; // doing shift/rotate instruction +reg rotate; // doing rotate (no shift) +reg backwards; // backwards branch +reg cond_true; // branch condition is true +reg [2:0] cond_code; // condition code bits from instruction +reg shift_right; // Instruction ALU shift/rotate right +reg alu_shift_right; // Current cycle shift right enable +reg [3:0] op; // Main ALU operation for instruction +reg [3:0] alu_op; // Current cycle ALU operation +reg adc_bcd; // ALU should do BCD style carry +reg adj_bcd; // results should be BCD adjusted + +/* + * some flip flops to remember we're doing special instructions. These + * get loaded at the DECODE state, and used later + */ +reg bit_ins; // doing BIT instruction +reg plp; // doing PLP instruction +reg php; // doing PHP instruction +reg clc; // clear carry +reg sec; // set carry +reg cld; // clear decimal +reg sed; // set decimal +reg cli; // clear interrupt +reg sei; // set interrupt +reg clv; // clear overflow +reg brk; // doing BRK + +reg res; // in reset + +/* + * ALU operations + */ + +parameter + OP_OR = 4'b1100, + OP_AND = 4'b1101, + OP_EOR = 4'b1110, + OP_ADD = 4'b0011, + OP_SUB = 4'b0111, + OP_ROL = 4'b1011, + OP_A = 4'b1111; + +/* + * Microcode state machine. Basically, every addressing mode has its own + * path through the state machine. Additional information, such as the + * operation, source and destination registers are decoded in parallel, and + * kept in separate flops. + */ + +parameter + ABS0 = 6'd0, // ABS - fetch LSB + ABS1 = 6'd1, // ABS - fetch MSB + ABSX0 = 6'd2, // ABS, X - fetch LSB and send to ALU (+X) + ABSX1 = 6'd3, // ABS, X - fetch MSB and send to ALU (+Carry) + ABSX2 = 6'd4, // ABS, X - Wait for ALU (only if needed) + BRA0 = 6'd5, // Branch - fetch offset and send to ALU (+PC[7:0]) + BRA1 = 6'd6, // Branch - fetch opcode, and send PC[15:8] to ALU + BRA2 = 6'd7, // Branch - fetch opcode (if page boundary crossed) + BRK0 = 6'd8, // BRK/IRQ - push PCH, send S to ALU (-1) + BRK1 = 6'd9, // BRK/IRQ - push PCL, send S to ALU (-1) + BRK2 = 6'd10, // BRK/IRQ - push P, send S to ALU (-1) + BRK3 = 6'd11, // BRK/IRQ - write S, and fetch @ fffe + DECODE = 6'd12, // IR is valid, decode instruction, and write prev reg + FETCH = 6'd13, // fetch next opcode, and perform prev ALU op + INDX0 = 6'd14, // (ZP,X) - fetch ZP address, and send to ALU (+X) + INDX1 = 6'd15, // (ZP,X) - fetch LSB at ZP+X, calculate ZP+X+1 + INDX2 = 6'd16, // (ZP,X) - fetch MSB at ZP+X+1 + INDX3 = 6'd17, // (ZP,X) - fetch data + INDY0 = 6'd18, // (ZP),Y - fetch ZP address, and send ZP to ALU (+1) + INDY1 = 6'd19, // (ZP),Y - fetch at ZP+1, and send LSB to ALU (+Y) + INDY2 = 6'd20, // (ZP),Y - fetch data, and send MSB to ALU (+Carry) + INDY3 = 6'd21, // (ZP),Y) - fetch data (if page boundary crossed) + JMP0 = 6'd22, // JMP - fetch PCL and hold + JMP1 = 6'd23, // JMP - fetch PCH + JMPI0 = 6'd24, // JMP IND - fetch LSB and send to ALU for delay (+0) + JMPI1 = 6'd25, // JMP IND - fetch MSB, proceed with JMP0 state + JSR0 = 6'd26, // JSR - push PCH, save LSB, send S to ALU (-1) + JSR1 = 6'd27, // JSR - push PCL, send S to ALU (-1) + JSR2 = 6'd28, // JSR - write S + JSR3 = 6'd29, // JSR - fetch MSB + PULL0 = 6'd30, // PLP/PLA - save next op in IRHOLD, send S to ALU (+1) + PULL1 = 6'd31, // PLP/PLA - fetch data from stack, write S + PULL2 = 6'd32, // PLP/PLA - prefetch op, but don't increment PC + PUSH0 = 6'd33, // PHP/PHA - send A to ALU (+0) + PUSH1 = 6'd34, // PHP/PHA - write A/P, send S to ALU (-1) + READ = 6'd35, // Read memory for read/modify/write (INC, DEC, shift) + REG = 6'd36, // Read register for reg-reg transfers + RTI0 = 6'd37, // RTI - send S to ALU (+1) + RTI1 = 6'd38, // RTI - read P from stack + RTI2 = 6'd39, // RTI - read PCL from stack + RTI3 = 6'd40, // RTI - read PCH from stack + RTI4 = 6'd41, // RTI - read PCH from stack + RTS0 = 6'd42, // RTS - send S to ALU (+1) + RTS1 = 6'd43, // RTS - read PCL from stack + RTS2 = 6'd44, // RTS - write PCL to ALU, read PCH + RTS3 = 6'd45, // RTS - load PC and increment + WRITE = 6'd46, // Write memory for read/modify/write + ZP0 = 6'd47, // Z-page - fetch ZP address + ZPX0 = 6'd48, // ZP, X - fetch ZP, and send to ALU (+X) + ZPX1 = 6'd49; // ZP, X - load from memory + +`ifdef SIM + +/* + * easy to read names in simulator output + */ +reg [8*6-1:0] statename; + +always @* + case( state ) + DECODE: statename = "DECODE"; + REG: statename = "REG"; + ZP0: statename = "ZP0"; + ZPX0: statename = "ZPX0"; + ZPX1: statename = "ZPX1"; + ABS0: statename = "ABS0"; + ABS1: statename = "ABS1"; + ABSX0: statename = "ABSX0"; + ABSX1: statename = "ABSX1"; + ABSX2: statename = "ABSX2"; + INDX0: statename = "INDX0"; + INDX1: statename = "INDX1"; + INDX2: statename = "INDX2"; + INDX3: statename = "INDX3"; + INDY0: statename = "INDY0"; + INDY1: statename = "INDY1"; + INDY2: statename = "INDY2"; + INDY3: statename = "INDY3"; + READ: statename = "READ"; + WRITE: statename = "WRITE"; + FETCH: statename = "FETCH"; + PUSH0: statename = "PUSH0"; + PUSH1: statename = "PUSH1"; + PULL0: statename = "PULL0"; + PULL1: statename = "PULL1"; + PULL2: statename = "PULL2"; + JSR0: statename = "JSR0"; + JSR1: statename = "JSR1"; + JSR2: statename = "JSR2"; + JSR3: statename = "JSR3"; + RTI0: statename = "RTI0"; + RTI1: statename = "RTI1"; + RTI2: statename = "RTI2"; + RTI3: statename = "RTI3"; + RTI4: statename = "RTI4"; + RTS0: statename = "RTS0"; + RTS1: statename = "RTS1"; + RTS2: statename = "RTS2"; + RTS3: statename = "RTS3"; + BRK0: statename = "BRK0"; + BRK1: statename = "BRK1"; + BRK2: statename = "BRK2"; + BRK3: statename = "BRK3"; + BRA0: statename = "BRA0"; + BRA1: statename = "BRA1"; + BRA2: statename = "BRA2"; + JMP0: statename = "JMP0"; + JMP1: statename = "JMP1"; + JMPI0: statename = "JMPI0"; + JMPI1: statename = "JMPI1"; + endcase + +//always @( PC ) +// $display( "%t, PC:%04x IR:%02x A:%02x X:%02x Y:%02x S:%02x C:%d Z:%d V:%d N:%d P:%02x", $time, PC, IR, A, X, Y, S, C, Z, V, N, P ); + +`endif + + + +/* + * Program Counter Increment/Load. First calculate the base value in + * PC_temp. + */ +always @* + case( state ) + DECODE: if( (~I & IRQ) | NMI_edge ) + PC_temp = { ABH, ABL }; + else + PC_temp = PC; + + + JMP1, + JMPI1, + JSR3, + RTS3, + RTI4: PC_temp = { DIMUX, ADD }; + + BRA1: PC_temp = { ABH, ADD }; + + BRA2: PC_temp = { ADD, PCL }; + + BRK2: PC_temp = res ? 16'hfffc : + NMI_edge ? 16'hfffa : 16'hfffe; + + default: PC_temp = PC; + endcase + +/* + * Determine wether we need PC_temp, or PC_temp + 1 + */ +always @* + case( state ) + DECODE: if( (~I & IRQ) | NMI_edge ) + PC_inc = 0; + else + PC_inc = 1; + + ABS0, + ABSX0, + FETCH, + BRA0, + BRA2, + BRK3, + JMPI1, + JMP1, + RTI4, + RTS3: PC_inc = 1; + + BRA1: PC_inc = CO ^~ backwards; + + default: PC_inc = 0; + endcase + +/* + * Set new PC + */ +always @(posedge clk) + if( RDY ) + PC <= PC_temp + PC_inc; + +/* + * Address Generator + */ + +parameter + ZEROPAGE = 8'h00, + STACKPAGE = 8'h01; + +always @* + case( state ) + ABSX1, + INDX3, + INDY2, + JMP1, + JMPI1, + RTI4, + ABS1: AB = { DIMUX, ADD }; + + BRA2, + INDY3, + ABSX2: AB = { ADD, ABL }; + + BRA1: AB = { ABH, ADD }; + + JSR0, + PUSH1, + RTS0, + RTI0, + BRK0: AB = { STACKPAGE, regfile }; + + BRK1, + JSR1, + PULL1, + RTS1, + RTS2, + RTI1, + RTI2, + RTI3, + BRK2: AB = { STACKPAGE, ADD }; + + INDY1, + INDX1, + ZPX1, + INDX2: AB = { ZEROPAGE, ADD }; + + ZP0, + INDY0: AB = { ZEROPAGE, DIMUX }; + + REG, + READ, + WRITE: AB = { ABH, ABL }; + + default: AB = PC; + endcase + +/* + * ABH/ABL pair is used for registering previous address bus state. + * This can be used to keep the current address, freeing up the original + * source of the address, such as the ALU or DI. + */ +always @(posedge clk) + if( state != PUSH0 && state != PUSH1 && RDY && + state != PULL0 && state != PULL1 && state != PULL2 ) + begin + ABL <= AB[7:0]; + ABH <= AB[15:8]; + end + +/* + * Data Out MUX + */ +always @* + case( state ) + WRITE: DO = ADD; + + JSR0, + BRK0: DO = PCH; + + JSR1, + BRK1: DO = PCL; + + PUSH1: DO = php ? P : ADD; + + BRK2: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P; + + default: DO = regfile; + endcase + +/* + * Write Enable Generator + */ + +always @* + case( state ) + BRK0, // writing to stack or memory + BRK1, + BRK2, + JSR0, + JSR1, + PUSH1, + WRITE: WE = 1; + + INDX3, // only if doing a STA, STX or STY + INDY3, + ABSX2, + ABS1, + ZPX1, + ZP0: WE = store; + + default: WE = 0; + endcase + +/* + * register file, contains A, X, Y and S (stack pointer) registers. At each + * cycle only 1 of those registers needs to be accessed, so they combined + * in a small memory, saving resources. + */ + +reg write_register; // set when register file is written + +always @* + case( state ) + DECODE: write_register = load_reg & ~plp; + + PULL1, + RTS2, + RTI3, + BRK3, + JSR0, + JSR2 : write_register = 1; + + default: write_register = 0; + endcase + +/* + * BCD adjust logic + */ + +always @(posedge clk) + adj_bcd <= adc_sbc & D; // '1' when doing a BCD instruction + +reg [3:0] ADJL; +reg [3:0] ADJH; + +// adjustment term to be added to ADD[3:0] based on the following +// adj_bcd: '1' if doing ADC/SBC with D=1 +// adc_bcd: '1' if doing ADC with D=1 +// HC : half carry bit from ALU +always @* begin + casex( {adj_bcd, adc_bcd, HC} ) + 3'b0xx: ADJL = 4'd0; // no BCD instruction + 3'b100: ADJL = 4'd10; // SBC, and digital borrow + 3'b101: ADJL = 4'd0; // SBC, but no borrow + 3'b110: ADJL = 4'd0; // ADC, but no carry + 3'b111: ADJL = 4'd6; // ADC, and decimal/digital carry + endcase +end + +// adjustment term to be added to ADD[7:4] based on the following +// adj_bcd: '1' if doing ADC/SBC with D=1 +// adc_bcd: '1' if doing ADC with D=1 +// CO : carry out bit from ALU +always @* begin + casex( {adj_bcd, adc_bcd, CO} ) + 3'b0xx: ADJH = 4'd0; // no BCD instruction + 3'b100: ADJH = 4'd10; // SBC, and digital borrow + 3'b101: ADJH = 4'd0; // SBC, but no borrow + 3'b110: ADJH = 4'd0; // ADC, but no carry + 3'b111: ADJH = 4'd6; // ADC, and decimal/digital carry + endcase +end + +/* + * write to a register. Usually this is the (BCD corrected) output of the + * ALU, but in case of the JSR0 we use the S register to temporarily store + * the PCL. This is possible, because the S register itself is stored in + * the ALU during those cycles. + */ +always @(posedge clk) + if( write_register & RDY ) + AXYS[regsel] <= (state == JSR0) ? DIMUX : { ADD[7:4] + ADJH, ADD[3:0] + ADJL }; + +/* + * register select logic. This determines which of the A, X, Y or + * S registers will be accessed. + */ + +always @* + case( state ) + INDY1, + INDX0, + ZPX0, + ABSX0 : regsel = index_y ? SEL_Y : SEL_X; + + + DECODE : regsel = dst_reg; + + BRK0, + BRK3, + JSR0, + JSR2, + PULL0, + PULL1, + PUSH1, + RTI0, + RTI3, + RTS0, + RTS2 : regsel = SEL_S; + + default: regsel = src_reg; + endcase + +/* + * ALU + */ + +ALU ALU( .clk(clk), + .op(alu_op), + .right(alu_shift_right), + .AI(AI), + .BI(BI), + .CI(CI), + .BCD(adc_bcd & (state == FETCH)), + .CO(CO), + .OUT(ADD), + .V(AV), + .Z(AZ), + .N(AN), + .HC(HC), + .RDY(RDY) ); + +/* + * Select current ALU operation + */ + +always @* + case( state ) + READ: alu_op = op; + + BRA1: alu_op = backwards ? OP_SUB : OP_ADD; + + FETCH, + REG : alu_op = op; + + DECODE, + ABS1: alu_op = 1'bx; + + PUSH1, + BRK0, + BRK1, + BRK2, + JSR0, + JSR1: alu_op = OP_SUB; + + default: alu_op = OP_ADD; + endcase + +/* + * Determine shift right signal to ALU + */ + +always @* + if( state == FETCH || state == REG || state == READ ) + alu_shift_right = shift_right; + else + alu_shift_right = 0; + +/* + * Sign extend branch offset. + */ + +always @(posedge clk) + if( RDY ) + backwards <= DIMUX[7]; + +/* + * ALU A Input MUX + */ + +always @* + case( state ) + JSR1, + RTS1, + RTI1, + RTI2, + BRK1, + BRK2, + INDX1: AI = ADD; + + REG, + ZPX0, + INDX0, + ABSX0, + RTI0, + RTS0, + JSR0, + JSR2, + BRK0, + PULL0, + INDY1, + PUSH0, + PUSH1: AI = regfile; + + BRA0, + READ: AI = DIMUX; + + BRA1: AI = ABH; // don't use PCH in case we're + + FETCH: AI = load_only ? 0 : regfile; + + DECODE, + ABS1: AI = 8'hxx; // don't care + + default: AI = 0; + endcase + + +/* + * ALU B Input mux + */ + +always @* + case( state ) + BRA1, + RTS1, + RTI0, + RTI1, + RTI2, + INDX1, + READ, + REG, + JSR0, + JSR1, + JSR2, + BRK0, + BRK1, + BRK2, + PUSH0, + PUSH1, + PULL0, + RTS0: BI = 8'h00; + + BRA0: BI = PCL; + + DECODE, + ABS1: BI = 8'hxx; + + default: BI = DIMUX; + endcase + +/* + * ALU CI (carry in) mux + */ + +always @* + case( state ) + INDY2, + BRA1, + ABSX1: CI = CO; + + DECODE, + ABS1: CI = 1'bx; + + READ, + REG: CI = rotate ? C : + shift ? 0 : inc; + + FETCH: CI = rotate ? C : + compare ? 1 : + (shift | load_only) ? 0 : C; + + PULL0, + RTI0, + RTI1, + RTI2, + RTS0, + RTS1, + INDY0, + INDX1: CI = 1; + + default: CI = 0; + endcase + +/* + * Processor Status Register update + * + */ + +/* + * Update C flag when doing ADC/SBC, shift/rotate, compare + */ +always @(posedge clk ) + if( shift && state == WRITE ) + C <= CO; + else if( state == RTI2 ) + C <= DIMUX[0]; + else if( ~write_back && state == DECODE ) begin + if( adc_sbc | shift | compare ) + C <= CO; + else if( plp ) + C <= ADD[0]; + else begin + if( sec ) C <= 1; + if( clc ) C <= 0; + end + end + +/* + * Update Z, N flags when writing A, X, Y, Memory, or when doing compare + */ + +always @(posedge clk) + if( state == WRITE ) + Z <= AZ; + else if( state == RTI2 ) + Z <= DIMUX[1]; + else if( state == DECODE ) begin + if( plp ) + Z <= ADD[1]; + else if( (load_reg & (regsel != SEL_S)) | compare | bit_ins ) + Z <= AZ; + end + +always @(posedge clk) + if( state == WRITE ) + N <= AN; + else if( state == RTI2 ) + N <= DIMUX[7]; + else if( state == DECODE ) begin + if( plp ) + N <= ADD[7]; + else if( (load_reg & (regsel != SEL_S)) | compare ) + N <= AN; + end else if( state == FETCH && bit_ins ) + N <= DIMUX[7]; + +/* + * Update I flag + */ + +always @(posedge clk) + if( state == BRK3 ) + I <= 1; + else if( state == RTI2 ) + I <= DIMUX[2]; + else if( state == REG ) begin + if( sei ) I <= 1; + if( cli ) I <= 0; + end else if( state == DECODE ) + if( plp ) I <= ADD[2]; + +/* + * Update D flag + */ +always @(posedge clk ) + if( state == RTI2 ) + D <= DIMUX[3]; + else if( state == DECODE ) begin + if( sed ) D <= 1; + if( cld ) D <= 0; + if( plp ) D <= ADD[3]; + end + +/* + * Update V flag + */ +always @(posedge clk ) + if( state == RTI2 ) + V <= DIMUX[6]; + else if( state == DECODE ) begin + if( adc_sbc ) V <= AV; + if( clv ) V <= 0; + if( plp ) V <= ADD[6]; + end else if( state == FETCH && bit_ins ) + V <= DIMUX[6]; + +/* + * Instruction decoder + */ + +/* + * IR register/mux. Hold previous DI value in IRHOLD in PULL0 and PUSH0 + * states. In these states, the IR has been prefetched, and there is no + * time to read the IR again before the next decode. + */ + +always @(posedge clk ) + if( reset ) + IRHOLD_valid <= 0; + else if( RDY ) begin + if( state == PULL0 || state == PUSH0 ) begin + IRHOLD <= DIMUX; + IRHOLD_valid <= 1; + end else if( state == DECODE ) + IRHOLD_valid <= 0; + end + +assign IR = (IRQ & ~I) | NMI_edge ? 8'h00 : + IRHOLD_valid ? IRHOLD : DIMUX; + +always @(posedge clk ) + if( RDY ) + DIHOLD <= DI; + +assign DIMUX = ~RDY ? DIHOLD : DI; + +/* + * Microcode state machine + */ +always @(posedge clk or posedge reset) + if( reset ) + state <= BRK0; + else if( RDY ) case( state ) + DECODE : + casex ( IR ) + 8'b0000_0000: state <= BRK0; + 8'b0010_0000: state <= JSR0; + 8'b0010_1100: state <= ABS0; // BIT abs + 8'b0100_0000: state <= RTI0; // + 8'b0100_1100: state <= JMP0; + 8'b0110_0000: state <= RTS0; + 8'b0110_1100: state <= JMPI0; + 8'b0x00_1000: state <= PUSH0; + 8'b0x10_1000: state <= PULL0; + 8'b0xx1_1000: state <= REG; // CLC, SEC, CLI, SEI + 8'b1xx0_00x0: state <= FETCH; // IMM + 8'b1xx0_1100: state <= ABS0; // X/Y abs + 8'b1xxx_1000: state <= REG; // DEY, TYA, ... + 8'bxxx0_0001: state <= INDX0; + 8'bxxx0_01xx: state <= ZP0; + 8'bxxx0_1001: state <= FETCH; // IMM + 8'bxxx0_1101: state <= ABS0; // even E column + 8'bxxx0_1110: state <= ABS0; // even E column + 8'bxxx1_0000: state <= BRA0; // odd 0 column + 8'bxxx1_0001: state <= INDY0; // odd 1 column + 8'bxxx1_01xx: state <= ZPX0; // odd 4,5,6,7 columns + 8'bxxx1_1001: state <= ABSX0; // odd 9 column + 8'bxxx1_11xx: state <= ABSX0; // odd C, D, E, F columns + 8'bxxxx_1010: state <= REG; // A, TXA, ... NOP + endcase + + ZP0 : state <= write_back ? READ : FETCH; + + ZPX0 : state <= ZPX1; + ZPX1 : state <= write_back ? READ : FETCH; + + ABS0 : state <= ABS1; + ABS1 : state <= write_back ? READ : FETCH; + + ABSX0 : state <= ABSX1; + ABSX1 : state <= (CO | store | write_back) ? ABSX2 : FETCH; + ABSX2 : state <= write_back ? READ : FETCH; + + INDX0 : state <= INDX1; + INDX1 : state <= INDX2; + INDX2 : state <= INDX3; + INDX3 : state <= FETCH; + + INDY0 : state <= INDY1; + INDY1 : state <= INDY2; + INDY2 : state <= (CO | store) ? INDY3 : FETCH; + INDY3 : state <= FETCH; + + READ : state <= WRITE; + WRITE : state <= FETCH; + FETCH : state <= DECODE; + + REG : state <= DECODE; + + PUSH0 : state <= PUSH1; + PUSH1 : state <= DECODE; + + PULL0 : state <= PULL1; + PULL1 : state <= PULL2; + PULL2 : state <= DECODE; + + JSR0 : state <= JSR1; + JSR1 : state <= JSR2; + JSR2 : state <= JSR3; + JSR3 : state <= FETCH; + + RTI0 : state <= RTI1; + RTI1 : state <= RTI2; + RTI2 : state <= RTI3; + RTI3 : state <= RTI4; + RTI4 : state <= DECODE; + + RTS0 : state <= RTS1; + RTS1 : state <= RTS2; + RTS2 : state <= RTS3; + RTS3 : state <= FETCH; + + BRA0 : state <= cond_true ? BRA1 : DECODE; + BRA1 : state <= (CO ^ backwards) ? BRA2 : DECODE; + BRA2 : state <= DECODE; + + JMP0 : state <= JMP1; + JMP1 : state <= DECODE; + + JMPI0 : state <= JMPI1; + JMPI1 : state <= JMP0; + + BRK0 : state <= BRK1; + BRK1 : state <= BRK2; + BRK2 : state <= BRK3; + BRK3 : state <= JMP0; + + endcase + +/* + * Additional control signals + */ + +always @(posedge clk) + if( reset ) + res <= 1; + else if( state == DECODE ) + res <= 0; + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0xx01010, // ASLA, ROLA, LSRA, RORA + 8'b0xxxxx01, // ORA, AND, EOR, ADC + 8'b100x10x0, // DEY, TYA, TXA, TXS + 8'b1010xxx0, // LDA/LDX/LDY + 8'b10111010, // TSX + 8'b1011x1x0, // LDX/LDY + 8'b11001010, // DEX + 8'b1x1xxx01, // LDA, SBC + 8'bxxx01000: // DEY, TAY, INY, INX + load_reg <= 1; + + default: load_reg <= 0; + endcase + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'b1110_1000, // INX + 8'b1100_1010, // DEX + 8'b101x_xx10: // LDX, TAX, TSX + dst_reg <= SEL_X; + + 8'b0x00_1000, // PHP, PHA + 8'b1001_1010: // TXS + dst_reg <= SEL_S; + + 8'b1x00_1000, // DEY, DEX + 8'b101x_x100, // LDY + 8'b1010_x000: // LDY #imm, TAY + dst_reg <= SEL_Y; + + default: dst_reg <= SEL_A; + endcase + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'b1011_1010: // TSX + src_reg <= SEL_S; + + 8'b100x_x110, // STX + 8'b100x_1x10, // TXA, TXS + 8'b1110_xx00, // INX, CPX + 8'b1100_1010: // DEX + src_reg <= SEL_X; + + 8'b100x_x100, // STY + 8'b1001_1000, // TYA + 8'b1100_xx00, // CPY + 8'b1x00_1000: // DEY, INY + src_reg <= SEL_Y; + + default: src_reg <= SEL_A; + endcase + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'bxxx1_0001, // INDY + 8'b10x1_x110, // LDX/STX zpg/abs, Y + 8'bxxxx_1001: // abs, Y + index_y <= 1; + + default: index_y <= 0; + endcase + + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'b100x_x1x0, // STX, STY + 8'b100x_xx01: // STA + store <= 1; + + default: store <= 0; + + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0xxx_x110, // ASL, ROL, LSR, ROR + 8'b11xx_x110: // DEC/INC + write_back <= 1; + + default: write_back <= 0; + endcase + + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b101x_xxxx: // LDA, LDX, LDY + load_only <= 1; + default: load_only <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b111x_x110, // INC + 8'b11x0_1000: // INX, INY + inc <= 1; + + default: inc <= 0; + endcase + +always @(posedge clk ) + if( (state == DECODE || state == BRK0) && RDY ) + casex( IR ) + 8'bx11x_xx01: // SBC, ADC + adc_sbc <= 1; + + default: adc_sbc <= 0; + endcase + +always @(posedge clk ) + if( (state == DECODE || state == BRK0) && RDY ) + casex( IR ) + 8'b011x_xx01: // ADC + adc_bcd <= D; + + default: adc_bcd <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0xxx_x110, // ASL, ROL, LSR, ROR (abs, absx, zpg, zpgx) + 8'b0xxx_1010: // ASL, ROL, LSR, ROR (acc) + shift <= 1; + + default: shift <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b11x0_0x00, // CPX, CPY (imm/zp) + 8'b11x0_1100, // CPX, CPY (abs) + 8'b110x_xx01: // CMP + compare <= 1; + + default: compare <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b01xx_xx10: // ROR, LSR + shift_right <= 1; + + default: shift_right <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0x1x_1010, // ROL A, ROR A + 8'b0x1x_x110: // ROR, ROL + rotate <= 1; + + default: rotate <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b00xx_xx10: // ROL, ASL + op <= OP_ROL; + + 8'b0010_x100: // BIT zp/abs + op <= OP_AND; + + 8'b01xx_xx10: // ROR, LSR + op <= OP_A; + + 8'b1000_1000, // DEY + 8'b1100_1010, // DEX + 8'b110x_x110, // DEC + 8'b11xx_xx01, // CMP, SBC + 8'b11x0_0x00, // CPX, CPY (imm, zpg) + 8'b11x0_1100: op <= OP_SUB; + + 8'b010x_xx01, // EOR + 8'b00xx_xx01: // ORA, AND + op <= { 2'b11, IR[6:5] }; + + default: op <= OP_ADD; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0010_x100: // BIT zp/abs + bit_ins <= 1; + + default: bit_ins <= 0; + endcase + +/* + * special instructions + */ +always @(posedge clk ) + if( state == DECODE && RDY ) begin + php <= (IR == 8'h08); + clc <= (IR == 8'h18); + plp <= (IR == 8'h28); + sec <= (IR == 8'h38); + cli <= (IR == 8'h58); + sei <= (IR == 8'h78); + clv <= (IR == 8'hb8); + cld <= (IR == 8'hd8); + sed <= (IR == 8'hf8); + brk <= (IR == 8'h00); + end + +always @(posedge clk) + if( RDY ) + cond_code <= IR[7:5]; + +always @* + case( cond_code ) + 3'b000: cond_true = ~N; + 3'b001: cond_true = N; + 3'b010: cond_true = ~V; + 3'b011: cond_true = V; + 3'b100: cond_true = ~C; + 3'b101: cond_true = C; + 3'b110: cond_true = ~Z; + 3'b111: cond_true = Z; + endcase + + +reg NMI_1 = 0; // delayed NMI signal + +always @(posedge clk) + NMI_1 <= NMI; + +always @(posedge clk ) + if( NMI_edge && state == BRK3 ) + NMI_edge <= 0; + else if( NMI & ~NMI_1 ) + NMI_edge <= 1; + +endmodule diff --git a/hw/efinix_fpga/simulation/src/verilog-6502/cpu_65c02.v b/hw/efinix_fpga/simulation/src/verilog-6502/cpu_65c02.v new file mode 100644 index 0000000..967b7a3 --- /dev/null +++ b/hw/efinix_fpga/simulation/src/verilog-6502/cpu_65c02.v @@ -0,0 +1,1418 @@ +/* + * verilog model of 65C02 CPU. + * + * Based on original 6502 "Arlet 6502 Core" by Arlet Ottens + * + * (C) Arlet Ottens, + * + * Feel free to use this code in any project (commercial or not), as long as you + * keep this message, and the copyright notice. This code is provided "as is", + * without any warranties of any kind. + * + * Support for 65C02 instructions and addressing modes by David Banks and Ed Spittles + * + * (C) 2016 David Banks and Ed Spittles + * + * Feel free to use this code in any project (commercial or not), as long as you + * keep this message, and the copyright notice. This code is provided "as is", + * without any warranties of any kind. + * + */ + +/* + * Note that not all 6502 interface signals are supported (yet). The goal + * is to create an Acorn Atom model, and the Atom didn't use all signals on + * the main board. + * + * The data bus is implemented as separate read/write buses. Combine them + * on the output pads if external memory is required. + */ + +/* + * Two things were needed to correctly implement 65C02 NOPs + * 1. Ensure the microcode state machine uses an appropriate addressing mode for the opcode length + * 2. Ensure there are no side-effects (e.g. register updates, memory stores, etc) + * + * If IMPLEMENT_NOPS is defined, the state machine is modified accordingly. + */ + +`define IMPLEMENT_NOPS + +/* + * Two things were needed to correctly implement 65C02 BCD arithmentic + * 1. The Z flag needs calculating over the BCD adjusted ALU output + * 2. The N flag needs calculating over the BCD adjusted ALU output + * + * If IMPLEMENT_CORRECT_BCD_FLAGS is defined, this additional logic is added + */ + +// `define IMPLEMENT_CORRECT_BCD_FLAGS + +module cpu_65c02( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY, SYNC ); + +input clk; // CPU clock +input reset; // reset signal +output reg [15:0] AB; // address bus +input [7:0] DI; // data in, read bus +output [7:0] DO; // data out, write bus +output WE; // write enable +input IRQ; // interrupt request +input NMI; // non-maskable interrupt request +input RDY; // Ready signal. Pauses CPU when RDY=0 +output reg SYNC; // AB is first cycle of the intruction + +/* + * internal signals + */ + +reg [15:0] PC; // Program Counter +reg [7:0] ABL; // Address Bus Register LSB +reg [7:0] ABH; // Address Bus Register MSB +wire [7:0] ADD; // Adder Hold Register (registered in ALU) + +reg [7:0] DIHOLD; // Hold for Data In +reg DIHOLD_valid; // +wire [7:0] DIMUX; // + +reg [7:0] IRHOLD; // Hold for Instruction register +reg IRHOLD_valid; // Valid instruction in IRHOLD + +reg [7:0] AXYS[3:0]; // A, X, Y and S register file + +reg C = 0; // carry flag (init at zero to avoid X's in ALU sim) +reg Z = 0; // zero flag +reg I = 0; // interrupt flag +reg D = 0; // decimal flag +reg V = 0; // overflow flag +reg N = 0; // negative flag +wire AZ; // ALU Zero flag +wire AZ1; // ALU Zero flag (BCD adjusted) +reg AZ2; // ALU Second Zero flag, set using TSB/TRB semantics +wire AV; // ALU overflow flag +wire AN; // ALU negative flag +wire AN1; // ALU negative flag (BCD adjusted) +wire HC; // ALU half carry + +reg [7:0] AI; // ALU Input A +reg [7:0] BI; // ALU Input B +wire [7:0] DI; // Data In +wire [7:0] IR; // Instruction register +reg [7:0] DO; // Data Out +wire [7:0] AO; // ALU output after BCD adjustment +reg WE; // Write Enable +reg CI; // Carry In +wire CO; // Carry Out +wire [7:0] PCH = PC[15:8]; +wire [7:0] PCL = PC[7:0]; + +reg NMI_edge = 0; // captured NMI edge + +reg [1:0] regsel; // Select A, X, Y or S register +wire [7:0] regfile = AXYS[regsel]; // Selected register output + +parameter + SEL_A = 2'd0, + SEL_S = 2'd1, + SEL_X = 2'd2, + SEL_Y = 2'd3; + +/* + * define some signals for watching in simulator output + */ + + +`ifdef SIM +wire [7:0] A = AXYS[SEL_A]; // Accumulator +wire [7:0] X = AXYS[SEL_X]; // X register +wire [7:0] Y = AXYS[SEL_Y]; // Y register +wire [7:0] S = AXYS[SEL_S]; // Stack pointer +`endif + +wire [7:0] P = { N, V, 2'b11, D, I, Z, C }; + +/* + * instruction decoder/sequencer + */ + +reg [5:0] state; + +/* + * control signals + */ + +reg PC_inc; // Increment PC +reg [15:0] PC_temp; // intermediate value of PC + +reg [1:0] src_reg; // source register index +reg [1:0] dst_reg; // destination register index + +reg index_y; // if set, then Y is index reg rather than X +reg load_reg; // loading a register (A, X, Y, S) in this instruction +reg inc; // increment +reg write_back; // set if memory is read/modified/written +reg load_only; // LDA/LDX/LDY instruction +reg store; // doing store (STA/STX/STY) +reg adc_sbc; // doing ADC/SBC +reg compare; // doing CMP/CPY/CPX +reg shift; // doing shift/rotate instruction +reg rotate; // doing rotate (no shift) +reg backwards; // backwards branch +reg cond_true; // branch condition is true +reg [3:0] cond_code; // condition code bits from instruction +reg shift_right; // Instruction ALU shift/rotate right +reg alu_shift_right; // Current cycle shift right enable +reg [3:0] op; // Main ALU operation for instruction +reg [3:0] alu_op; // Current cycle ALU operation +reg adc_bcd; // ALU should do BCD style carry +reg adj_bcd; // results should be BCD adjusted + +/* + * some flip flops to remember we're doing special instructions. These + * get loaded at the DECODE state, and used later + */ +reg store_zero; // doing STZ instruction +reg trb_ins; // doing TRB instruction +reg txb_ins; // doing TSB/TRB instruction +reg bit_ins; // doing BIT instruction +reg bit_ins_nv; // doing BIT instruction that will update the n and v flags (i.e. not BIT imm) +reg plp; // doing PLP instruction +reg php; // doing PHP instruction +reg clc; // clear carry +reg sec; // set carry +reg cld; // clear decimal +reg sed; // set decimal +reg cli; // clear interrupt +reg sei; // set interrupt +reg clv; // clear overflow + +reg res; // in reset + +/* + * ALU operations + */ + +parameter + OP_OR = 4'b1100, + OP_AND = 4'b1101, + OP_EOR = 4'b1110, + OP_ADD = 4'b0011, + OP_SUB = 4'b0111, + OP_ROL = 4'b1011, + OP_A = 4'b1111; + +/* + * Microcode state machine. Basically, every addressing mode has its own + * path through the state machine. Additional information, such as the + * operation, source and destination registers are decoded in parallel, and + * kept in separate flops. + */ + +parameter + ABS0 = 6'd0, // ABS - fetch LSB + ABS1 = 6'd1, // ABS - fetch MSB + ABSX0 = 6'd2, // ABS, X - fetch LSB and send to ALU (+X) + ABSX1 = 6'd3, // ABS, X - fetch MSB and send to ALU (+Carry) + ABSX2 = 6'd4, // ABS, X - Wait for ALU (only if needed) + BRA0 = 6'd5, // Branch - fetch offset and send to ALU (+PC[7:0]) + BRA1 = 6'd6, // Branch - fetch opcode, and send PC[15:8] to ALU + BRA2 = 6'd7, // Branch - fetch opcode (if page boundary crossed) + BRK0 = 6'd8, // BRK/IRQ - push PCH, send S to ALU (-1) + BRK1 = 6'd9, // BRK/IRQ - push PCL, send S to ALU (-1) + BRK2 = 6'd10, // BRK/IRQ - push P, send S to ALU (-1) + BRK3 = 6'd11, // BRK/IRQ - write S, and fetch @ fffe + DECODE = 6'd12, // IR is valid, decode instruction, and write prev reg + FETCH = 6'd13, // fetch next opcode, and perform prev ALU op + INDX0 = 6'd14, // (ZP,X) - fetch ZP address, and send to ALU (+X) + INDX1 = 6'd15, // (ZP,X) - fetch LSB at ZP+X, calculate ZP+X+1 + INDX2 = 6'd16, // (ZP,X) - fetch MSB at ZP+X+1 + INDX3 = 6'd17, // (ZP,X) - fetch data + INDY0 = 6'd18, // (ZP),Y - fetch ZP address, and send ZP to ALU (+1) + INDY1 = 6'd19, // (ZP),Y - fetch at ZP+1, and send LSB to ALU (+Y) + INDY2 = 6'd20, // (ZP),Y - fetch data, and send MSB to ALU (+Carry) + INDY3 = 6'd21, // (ZP),Y) - fetch data (if page boundary crossed) + JMP0 = 6'd22, // JMP - fetch PCL and hold + JMP1 = 6'd23, // JMP - fetch PCH + JMPI0 = 6'd24, // JMP IND - fetch LSB and send to ALU for delay (+0) + JMPI1 = 6'd25, // JMP IND - fetch MSB, proceed with JMP0 state + JSR0 = 6'd26, // JSR - push PCH, save LSB, send S to ALU (-1) + JSR1 = 6'd27, // JSR - push PCL, send S to ALU (-1) + JSR2 = 6'd28, // JSR - write S + JSR3 = 6'd29, // JSR - fetch MSB + PULL0 = 6'd30, // PLP/PLA/PLX/PLY - save next op in IRHOLD, send S to ALU (+1) + PULL1 = 6'd31, // PLP/PLA/PLX/PLY - fetch data from stack, write S + PULL2 = 6'd32, // PLP/PLA/PLX/PLY - prefetch op, but don't increment PC + PUSH0 = 6'd33, // PHP/PHA/PHX/PHY - send A to ALU (+0) + PUSH1 = 6'd34, // PHP/PHA/PHX/PHY - write A/P, send S to ALU (-1) + READ = 6'd35, // Read memory for read/modify/write (INC, DEC, shift) + REG = 6'd36, // Read register for reg-reg transfers + RTI0 = 6'd37, // RTI - send S to ALU (+1) + RTI1 = 6'd38, // RTI - read P from stack + RTI2 = 6'd39, // RTI - read PCL from stack + RTI3 = 6'd40, // RTI - read PCH from stack + RTI4 = 6'd41, // RTI - read PCH from stack + RTS0 = 6'd42, // RTS - send S to ALU (+1) + RTS1 = 6'd43, // RTS - read PCL from stack + RTS2 = 6'd44, // RTS - write PCL to ALU, read PCH + RTS3 = 6'd45, // RTS - load PC and increment + WRITE = 6'd46, // Write memory for read/modify/write + ZP0 = 6'd47, // Z-page - fetch ZP address + ZPX0 = 6'd48, // ZP, X - fetch ZP, and send to ALU (+X) + ZPX1 = 6'd49, // ZP, X - load from memory + IND0 = 6'd50, // (ZP) - fetch ZP address, and send to ALU (+0) + JMPIX0 = 6'd51, // JMP (,X)- fetch LSB and send to ALU (+X) + JMPIX1 = 6'd52, // JMP (,X)- fetch MSB and send to ALU (+Carry) + JMPIX2 = 6'd53; // JMP (,X)- Wait for ALU (only if needed) + +`ifdef SIM + +/* + * easy to read names in simulator output + */ +reg [8*6-1:0] statename; + +always @* + case( state ) + DECODE: statename = "DECODE"; + REG: statename = "REG"; + ZP0: statename = "ZP0"; + ZPX0: statename = "ZPX0"; + ZPX1: statename = "ZPX1"; + ABS0: statename = "ABS0"; + ABS1: statename = "ABS1"; + ABSX0: statename = "ABSX0"; + ABSX1: statename = "ABSX1"; + ABSX2: statename = "ABSX2"; + IND0: statename = "IND0"; + INDX0: statename = "INDX0"; + INDX1: statename = "INDX1"; + INDX2: statename = "INDX2"; + INDX3: statename = "INDX3"; + INDY0: statename = "INDY0"; + INDY1: statename = "INDY1"; + INDY2: statename = "INDY2"; + INDY3: statename = "INDY3"; + READ: statename = "READ"; + WRITE: statename = "WRITE"; + FETCH: statename = "FETCH"; + PUSH0: statename = "PUSH0"; + PUSH1: statename = "PUSH1"; + PULL0: statename = "PULL0"; + PULL1: statename = "PULL1"; + PULL2: statename = "PULL2"; + JSR0: statename = "JSR0"; + JSR1: statename = "JSR1"; + JSR2: statename = "JSR2"; + JSR3: statename = "JSR3"; + RTI0: statename = "RTI0"; + RTI1: statename = "RTI1"; + RTI2: statename = "RTI2"; + RTI3: statename = "RTI3"; + RTI4: statename = "RTI4"; + RTS0: statename = "RTS0"; + RTS1: statename = "RTS1"; + RTS2: statename = "RTS2"; + RTS3: statename = "RTS3"; + BRK0: statename = "BRK0"; + BRK1: statename = "BRK1"; + BRK2: statename = "BRK2"; + BRK3: statename = "BRK3"; + BRA0: statename = "BRA0"; + BRA1: statename = "BRA1"; + BRA2: statename = "BRA2"; + JMP0: statename = "JMP0"; + JMP1: statename = "JMP1"; + JMPI0: statename = "JMPI0"; + JMPI1: statename = "JMPI1"; + JMPIX0: statename = "JMPIX0"; + JMPIX1: statename = "JMPIX1"; + JMPIX2: statename = "JMPIX2"; + + endcase + +//always @( PC ) +// $display( "%t, PC:%04x IR:%02x A:%02x X:%02x Y:%02x S:%02x C:%d Z:%d V:%d N:%d P:%02x", $time, PC, IR, A, X, Y, S, C, Z, V, N, P ); + +`endif + + + +/* + * Program Counter Increment/Load. First calculate the base value in + * PC_temp. + */ +always @* + case( state ) + DECODE: if( (~I & IRQ) | NMI_edge ) + PC_temp = { ABH, ABL }; + else + PC_temp = PC; + + + JMP1, + JMPI1, + JMPIX1, + JSR3, + RTS3, + RTI4: PC_temp = { DIMUX, ADD }; + + BRA1: PC_temp = { ABH, ADD }; + + JMPIX2, + BRA2: PC_temp = { ADD, PCL }; + + BRK2: PC_temp = res ? 16'hfffc : + NMI_edge ? 16'hfffa : 16'hfffe; + + default: PC_temp = PC; + endcase + +/* + * Determine wether we need PC_temp, or PC_temp + 1 + */ +always @* + case( state ) + DECODE: if( (~I & IRQ) | NMI_edge ) + PC_inc = 0; + else + PC_inc = 1; + + ABS0, + JMPIX0, + JMPIX2, + ABSX0, + FETCH, + BRA0, + BRA2, + BRK3, + JMPI1, + JMP1, + RTI4, + RTS3: PC_inc = 1; + + JMPIX1: PC_inc = ~CO; // Don't increment PC if we are going to go through JMPIX2 + + BRA1: PC_inc = CO ^~ backwards; + + default: PC_inc = 0; + endcase + +/* + * Set new PC + */ +always @(posedge clk) + if( RDY ) + PC <= PC_temp + PC_inc; + +/* + * Address Generator + */ + +parameter + ZEROPAGE = 8'h00, + STACKPAGE = 8'h01; + +always @* + case( state ) + JMPIX1, + ABSX1, + INDX3, + INDY2, + JMP1, + JMPI1, + RTI4, + ABS1: AB = { DIMUX, ADD }; + + BRA2, + INDY3, + JMPIX2, + ABSX2: AB = { ADD, ABL }; + + BRA1: AB = { ABH, ADD }; + + JSR0, + PUSH1, + RTS0, + RTI0, + BRK0: AB = { STACKPAGE, regfile }; + + BRK1, + JSR1, + PULL1, + RTS1, + RTS2, + RTI1, + RTI2, + RTI3, + BRK2: AB = { STACKPAGE, ADD }; + + INDY1, + INDX1, + ZPX1, + INDX2: AB = { ZEROPAGE, ADD }; + + ZP0, + INDY0: AB = { ZEROPAGE, DIMUX }; + + REG, + READ, + WRITE: AB = { ABH, ABL }; + + default: AB = PC; + endcase + +/* + * ABH/ABL pair is used for registering previous address bus state. + * This can be used to keep the current address, freeing up the original + * source of the address, such as the ALU or DI. + */ +always @(posedge clk) + if( state != PUSH0 && state != PUSH1 && RDY && + state != PULL0 && state != PULL1 && state != PULL2 ) + begin + ABL <= AB[7:0]; + ABH <= AB[15:8]; + end + +/* + * Data Out MUX + */ +always @* + case( state ) + WRITE: DO = ADD; + + JSR0, + BRK0: DO = PCH; + + JSR1, + BRK1: DO = PCL; + + PUSH1: DO = php ? P : ADD; + + BRK2: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P; + + default: DO = store_zero ? 8'b0 : regfile; + endcase + +/* + * Write Enable Generator + */ + +always @* + case( state ) + BRK0, // writing to stack or memory + BRK1, + BRK2, + JSR0, + JSR1, + PUSH1, + WRITE: WE = 1; + + INDX3, // only if doing a STA, STX or STY + INDY3, + ABSX2, + ABS1, + ZPX1, + ZP0: WE = store; + + default: WE = 0; + endcase + +/* + * register file, contains A, X, Y and S (stack pointer) registers. At each + * cycle only 1 of those registers needs to be accessed, so they combined + * in a small memory, saving resources. + */ + +reg write_register; // set when register file is written + +always @* + case( state ) + DECODE: write_register = load_reg & ~plp; + + PULL1, + RTS2, + RTI3, + BRK3, + JSR0, + JSR2 : write_register = 1; + + default: write_register = 0; + endcase + +/* + * BCD adjust logic + */ + +always @(posedge clk) + adj_bcd <= adc_sbc & D; // '1' when doing a BCD instruction + +reg [3:0] ADJL; +reg [3:0] ADJH; + +// adjustment term to be added to ADD[3:0] based on the following +// adj_bcd: '1' if doing ADC/SBC with D=1 +// adc_bcd: '1' if doing ADC with D=1 +// HC : half carry bit from ALU +always @* begin + casex( {adj_bcd, adc_bcd, HC} ) + 3'b0xx: ADJL = 4'd0; // no BCD instruction + 3'b100: ADJL = 4'd10; // SBC, and digital borrow + 3'b101: ADJL = 4'd0; // SBC, but no borrow + 3'b110: ADJL = 4'd0; // ADC, but no carry + 3'b111: ADJL = 4'd6; // ADC, and decimal/digital carry + endcase +end + +// adjustment term to be added to ADD[7:4] based on the following +// adj_bcd: '1' if doing ADC/SBC with D=1 +// adc_bcd: '1' if doing ADC with D=1 +// CO : carry out bit from ALU +always @* begin + casex( {adj_bcd, adc_bcd, CO} ) + 3'b0xx: ADJH = 4'd0; // no BCD instruction + 3'b100: ADJH = 4'd10; // SBC, and digital borrow + 3'b101: ADJH = 4'd0; // SBC, but no borrow + 3'b110: ADJH = 4'd0; // ADC, but no carry + 3'b111: ADJH = 4'd6; // ADC, and decimal/digital carry + endcase +end + +assign AO = { ADD[7:4] + ADJH, ADD[3:0] + ADJL }; + +`ifdef IMPLEMENT_CORRECT_BCD_FLAGS + +assign AN1 = AO[7]; +assign AZ1 = ~|AO; + +`else + +assign AN1 = AN; +assign AZ1 = AZ; + +`endif + +/* + * write to a register. Usually this is the (BCD corrected) output of the + * ALU, but in case of the JSR0 we use the S register to temporarily store + * the PCL. This is possible, because the S register itself is stored in + * the ALU during those cycles. + */ +always @(posedge clk) + if( write_register & RDY ) + AXYS[regsel] <= (state == JSR0) ? DIMUX : AO; + +/* + * register select logic. This determines which of the A, X, Y or + * S registers will be accessed. + */ + +always @* + case( state ) + INDY1, + INDX0, + ZPX0, + JMPIX0, + ABSX0 : regsel = index_y ? SEL_Y : SEL_X; + + + DECODE : regsel = dst_reg; + + BRK0, + BRK3, + JSR0, + JSR2, + PULL0, + PULL1, + PUSH1, + RTI0, + RTI3, + RTS0, + RTS2 : regsel = SEL_S; + + default: regsel = src_reg; + endcase + +/* + * ALU + */ + +ALU ALU( .clk(clk), + .op(alu_op), + .right(alu_shift_right), + .AI(AI), + .BI(BI), + .CI(CI), + .BCD(adc_bcd & (state == FETCH)), + .CO(CO), + .OUT(ADD), + .V(AV), + .Z(AZ), + .N(AN), + .HC(HC), + .RDY(RDY) ); + +/* + * Select current ALU operation + */ + +always @* + case( state ) + READ: alu_op = op; + + BRA1: alu_op = backwards ? OP_SUB : OP_ADD; + + FETCH, + REG : alu_op = op; + + DECODE, + ABS1: alu_op = 1'bx; + + PUSH1, + BRK0, + BRK1, + BRK2, + JSR0, + JSR1: alu_op = OP_SUB; + + default: alu_op = OP_ADD; + endcase + +/* + * Determine shift right signal to ALU + */ + +always @* + if( state == FETCH || state == REG || state == READ ) + alu_shift_right = shift_right; + else + alu_shift_right = 0; + +/* + * Sign extend branch offset. + */ + +always @(posedge clk) + if( RDY ) + backwards <= DIMUX[7]; + +/* + * ALU A Input MUX + */ + +always @* + case( state ) + JSR1, + RTS1, + RTI1, + RTI2, + BRK1, + BRK2, + INDX1: AI = ADD; + + REG, + ZPX0, + INDX0, + JMPIX0, + ABSX0, + RTI0, + RTS0, + JSR0, + JSR2, + BRK0, + PULL0, + INDY1, + PUSH0, + PUSH1: AI = regfile; + + BRA0, + READ: AI = DIMUX; + + BRA1: AI = ABH; // don't use PCH in case we're + + FETCH: AI = load_only ? 8'b0 : regfile; + + DECODE, + ABS1: AI = 8'hxx; // don't care + + default: AI = 0; + endcase + + +/* + * ALU B Input mux + */ + +always @* + case( state ) + BRA1, + RTS1, + RTI0, + RTI1, + RTI2, + INDX1, + REG, + JSR0, + JSR1, + JSR2, + BRK0, + BRK1, + BRK2, + PUSH0, + PUSH1, + PULL0, + RTS0: BI = 8'h00; + + READ: BI = txb_ins ? (trb_ins ? ~regfile : regfile) : 8'h00; + + BRA0: BI = PCL; + + DECODE, + ABS1: BI = 8'hxx; + + default: BI = DIMUX; + endcase + +/* + * ALU CI (carry in) mux + */ + +always @* + case( state ) + INDY2, + BRA1, + JMPIX1, + ABSX1: CI = CO; + + DECODE, + ABS1: CI = 1'bx; + + READ, + REG: CI = rotate ? C : + shift ? 1'b0 : inc; + + FETCH: CI = rotate ? C : + compare ? 1'b1 : + (shift | load_only) ? 1'b0 : C; + + PULL0, + RTI0, + RTI1, + RTI2, + RTS0, + RTS1, + INDY0, + INDX1: CI = 1; + + default: CI = 0; + endcase + +/* + * Processor Status Register update + * + */ + +/* + * Update C flag when doing ADC/SBC, shift/rotate, compare + */ +always @(posedge clk ) + if( shift && state == WRITE ) + C <= CO; + else if( state == RTI2 ) + C <= DIMUX[0]; + else if( ~write_back && state == DECODE ) begin + if( adc_sbc | shift | compare ) + C <= CO; + else if( plp ) + C <= ADD[0]; + else begin + if( sec ) C <= 1; + if( clc ) C <= 0; + end + end + +/* + * Special Z flag got TRB/TSB + */ +always @(posedge clk) + if (RDY) + AZ2 <= ~|(AI & regfile); + +/* + * Update Z, N flags when writing A, X, Y, Memory, or when doing compare + */ + +always @(posedge clk) + if( state == WRITE) + Z <= txb_ins ? AZ2 : AZ1; + else if( state == RTI2 ) + Z <= DIMUX[1]; + else if( state == DECODE ) begin + if( plp ) + Z <= ADD[1]; + else if( (load_reg & (regsel != SEL_S)) | compare | bit_ins ) + Z <= AZ1; + end + +always @(posedge clk) + if( state == WRITE && ~txb_ins) + N <= AN1; + else if( state == RTI2 ) + N <= DIMUX[7]; + else if( state == DECODE ) begin + if( plp ) + N <= ADD[7]; + else if( (load_reg & (regsel != SEL_S)) | compare ) + N <= AN1; + end else if( state == FETCH && bit_ins_nv ) + N <= DIMUX[7]; + +/* + * Update I flag + */ + +always @(posedge clk) + if( state == BRK3 ) + I <= 1; + else if( state == RTI2 ) + I <= DIMUX[2]; + else if( state == REG ) begin + if( sei ) I <= 1; + if( cli ) I <= 0; + end else if( state == DECODE ) + if( plp ) I <= ADD[2]; + +/* + * Update D flag + */ +always @(posedge clk ) + if( state == RTI2 ) + D <= DIMUX[3]; + else if( state == DECODE ) begin + if( sed ) D <= 1; + if( cld ) D <= 0; + if( plp ) D <= ADD[3]; + end + +/* + * Update V flag + */ +always @(posedge clk ) + if( state == RTI2 ) + V <= DIMUX[6]; + else if( state == DECODE ) begin + if( adc_sbc ) V <= AV; + if( clv ) V <= 0; + if( plp ) V <= ADD[6]; + end else if( state == FETCH && bit_ins_nv ) + V <= DIMUX[6]; + +/* + * Instruction decoder + */ + +/* + * IR register/mux. Hold previous DI value in IRHOLD in PULL0 and PUSH0 + * states. In these states, the IR has been prefetched, and there is no + * time to read the IR again before the next decode. + */ + +//reg RDY1 = 1; + +//always @(posedge clk ) +// RDY1 <= RDY; + +//always @(posedge clk ) +// if( ~RDY && RDY1 ) +// DIHOLD <= DI; + +always @(posedge clk ) + if( reset ) + IRHOLD_valid <= 0; + else if( RDY ) begin + if( state == PULL0 || state == PUSH0 ) begin + IRHOLD <= DIMUX; + IRHOLD_valid <= 1; + end else if( state == DECODE ) + IRHOLD_valid <= 0; + end + +assign IR = (IRQ & ~I) | NMI_edge ? 8'h00 : + IRHOLD_valid ? IRHOLD : DIMUX; + +//assign DIMUX = ~RDY1 ? DIHOLD : DI; + +assign DIMUX = DI; + +/* + * Microcode state machine + */ +always @(posedge clk or posedge reset) + if( reset ) + state <= BRK0; + else if( RDY ) case( state ) + DECODE : + casex ( IR ) + // TODO Review for simplifications as in verilog the first matching case has priority + 8'b0000_0000: state <= BRK0; + 8'b0010_0000: state <= JSR0; + 8'b0010_1100: state <= ABS0; // BIT abs + 8'b1001_1100: state <= ABS0; // STZ abs + 8'b000x_1100: state <= ABS0; // TSB/TRB + 8'b0100_0000: state <= RTI0; // + 8'b0100_1100: state <= JMP0; + 8'b0110_0000: state <= RTS0; + 8'b0110_1100: state <= JMPI0; + 8'b0111_1100: state <= JMPIX0; +`ifdef IMPLEMENT_NOPS + 8'bxxxx_xx11: state <= REG; // (NOP1: 3/7/B/F column) + 8'bxxx0_0010: state <= FETCH; // (NOP2: 2 column, 4 column handled correctly below) + 8'bx1x1_1100: state <= ABS0; // (NOP3: C column) +`endif + 8'b0x00_1000: state <= PUSH0; + 8'b0x10_1000: state <= PULL0; + 8'b0xx1_1000: state <= REG; // CLC, SEC, CLI, SEI + 8'b11x0_00x0: state <= FETCH; // IMM + 8'b1x10_00x0: state <= FETCH; // IMM + 8'b1xx0_1100: state <= ABS0; // X/Y abs + 8'b1xxx_1000: state <= REG; // DEY, TYA, ... + 8'bxxx0_0001: state <= INDX0; + 8'bxxx1_0010: state <= IND0; // (ZP) odd 2 column + 8'b000x_0100: state <= ZP0; // TSB/TRB + 8'bxxx0_01xx: state <= ZP0; + 8'bxxx0_1001: state <= FETCH; // IMM + 8'bxxx0_1101: state <= ABS0; // even D column + 8'bxxx0_1110: state <= ABS0; // even E column + 8'bxxx1_0000: state <= BRA0; // odd 0 column (Branches) + 8'b1000_0000: state <= BRA0; // BRA + 8'bxxx1_0001: state <= INDY0; // odd 1 column + 8'bxxx1_01xx: state <= ZPX0; // odd 4,5,6,7 columns + 8'bxxx1_1001: state <= ABSX0; // odd 9 column + 8'bx011_1100: state <= ABSX0; // C column BIT (3C), LDY (BC) + 8'bxxx1_11x1: state <= ABSX0; // odd D, F columns + 8'bxxx1_111x: state <= ABSX0; // odd E, F columns + 8'bx101_1010: state <= PUSH0; // PHX/PHY + 8'bx111_1010: state <= PULL0; // PLX/PLY + 8'bx0xx_1010: state <= REG; // A, TXA, ... NOP + 8'bxxx0_1010: state <= REG; // A, TXA, ... NOP + endcase + + ZP0 : state <= write_back ? READ : FETCH; + + ZPX0 : state <= ZPX1; + ZPX1 : state <= write_back ? READ : FETCH; + + ABS0 : state <= ABS1; + ABS1 : state <= write_back ? READ : FETCH; + + ABSX0 : state <= ABSX1; + ABSX1 : state <= (CO | store | write_back) ? ABSX2 : FETCH; + ABSX2 : state <= write_back ? READ : FETCH; + + JMPIX0 : state <= JMPIX1; + JMPIX1 : state <= CO ? JMPIX2 : JMP0; + JMPIX2 : state <= JMP0; + + IND0 : state <= INDX1; + + INDX0 : state <= INDX1; + INDX1 : state <= INDX2; + INDX2 : state <= INDX3; + INDX3 : state <= FETCH; + + INDY0 : state <= INDY1; + INDY1 : state <= INDY2; + INDY2 : state <= (CO | store) ? INDY3 : FETCH; + INDY3 : state <= FETCH; + + READ : state <= WRITE; + WRITE : state <= FETCH; + FETCH : state <= DECODE; + + REG : state <= DECODE; + + PUSH0 : state <= PUSH1; + PUSH1 : state <= DECODE; + + PULL0 : state <= PULL1; + PULL1 : state <= PULL2; + PULL2 : state <= DECODE; + + JSR0 : state <= JSR1; + JSR1 : state <= JSR2; + JSR2 : state <= JSR3; + JSR3 : state <= FETCH; + + RTI0 : state <= RTI1; + RTI1 : state <= RTI2; + RTI2 : state <= RTI3; + RTI3 : state <= RTI4; + RTI4 : state <= DECODE; + + RTS0 : state <= RTS1; + RTS1 : state <= RTS2; + RTS2 : state <= RTS3; + RTS3 : state <= FETCH; + + BRA0 : state <= cond_true ? BRA1 : DECODE; + BRA1 : state <= (CO ^ backwards) ? BRA2 : DECODE; + BRA2 : state <= DECODE; + + JMP0 : state <= JMP1; + JMP1 : state <= DECODE; + + JMPI0 : state <= JMPI1; + JMPI1 : state <= JMP0; + + BRK0 : state <= BRK1; + BRK1 : state <= BRK2; + BRK2 : state <= BRK3; + BRK3 : state <= JMP0; + + endcase + + +/* + * Sync state machine + */ +always @(posedge clk or posedge reset) + if( reset ) + SYNC <= 1'b0; + else if( RDY ) case( state ) + BRA0 : SYNC <= !cond_true; + BRA1 : SYNC <= !(CO ^ backwards); + BRA2, + FETCH, + REG, + PUSH1, + PULL2, + RTI4, + JMP1, + BRA2 : SYNC <= 1'b1; + default: SYNC <= 1'b0; + endcase + +//assign SYNC = state == DECODE; + +/* + * Additional control signals + */ + +always @(posedge clk) + if( reset ) + res <= 1; + else if( state == DECODE ) + res <= 0; + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) // DMB: Checked for 65C02 NOP collisions + 8'b0xx1_0010, // ORA, AND, EOR, ADC (zp) + 8'b1x11_0010, // LDA, SBC (zp) + 8'b0xxx_1010, // ASLA, INCA, ROLA, DECA, LSRA, PHY, RORA, PLY + 8'b0xxx_xx01, // ORA, AND, EOR, ADC + 8'b100x_10x0, // DEY, TYA, TXA, TXS + 8'b1010_xxx0, // LDA/LDX/LDY + 8'b1011_1010, // TSX + 8'b1011_x1x0, // LDX/LDY + 8'b1100_1010, // DEX + 8'b11x1_1010, // PHX, PLX + 8'b1x1x_xx01, // LDA, SBC + 8'bxxx0_1000: // PHP, PLP, PHA, PLA, DEY, TAY, INY, INX + load_reg <= 1; + + default: load_reg <= 0; + endcase + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'b1110_1000, // INX + 8'b1100_1010, // DEX + 8'b1111_1010, // PLX + 8'b1010_0010, // LDX imm + 8'b101x_x110, // LDX + 8'b101x_1x10: // LDX, TAX, TSX + dst_reg <= SEL_X; + + 8'b0x00_1000, // PHP, PHA + 8'bx101_1010, // PHX, PHY + 8'b1001_1010: // TXS + dst_reg <= SEL_S; + + 8'b1x00_1000, // DEY, DEX + 8'b0111_1010, // PLY + 8'b101x_x100, // LDY + 8'b1010_x000: // LDY #imm, TAY + dst_reg <= SEL_Y; + + default: dst_reg <= SEL_A; + endcase + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'b1011_1010: // TSX + src_reg <= SEL_S; + + 8'b100x_x110, // STX + 8'b100x_1x10, // TXA, TXS + 8'b1110_xx00, // INX, CPX + 8'b1101_1010, // PHX + 8'b1100_1010: // DEX + src_reg <= SEL_X; + + 8'b100x_x100, // STY + 8'b1001_1000, // TYA + 8'b1100_xx00, // CPY + 8'b0101_1010, // PHY + 8'b1x00_1000: // DEY, INY + src_reg <= SEL_Y; + + default: src_reg <= SEL_A; + endcase + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'bxxx1_0001, // INDY + 8'b10x1_0110, // LDX zp,Y / STX zp,Y + 8'b1011_1110, // LDX abs,Y + 8'bxxxx_1001: // abs, Y + index_y <= 1; + + default: index_y <= 0; + endcase + + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) // DMB: Checked for 65C02 NOP collisions + 8'b1001_0010, // STA (zp) + 8'b100x_x1x0, // STX, STY, STZ abs, STZ abs,x + 8'b011x_0100, // STZ zp, STZ zp,x + 8'b100x_xx01: // STA + store <= 1; + + default: store <= 0; + + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) // DMB: Checked for 65C02 NOP collisions + 8'b0xxx_x110, // ASL, ROL, LSR, ROR + 8'b000x_x100, // TSB/TRB + 8'b11xx_x110: // DEC/INC + write_back <= 1; + + default: write_back <= 0; + endcase + + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b101x_xxxx: // LDA, LDX, LDY + load_only <= 1; + default: load_only <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0001_1010, // INCA + 8'b111x_x110, // INC + 8'b11x0_1000: // INX, INY + inc <= 1; + + default: inc <= 0; + endcase + +always @(posedge clk ) + if( (state == DECODE || state == BRK0) && RDY ) + casex( IR ) + 8'bx111_0010, // SBC (zp), ADC (zp) + 8'bx11x_xx01: // SBC, ADC + adc_sbc <= 1; + + default: adc_sbc <= 0; + endcase + +always @(posedge clk ) + if( (state == DECODE || state == BRK0) && RDY ) + casex( IR ) + 8'b0111_0010, // ADC (zp) + 8'b011x_xx01: // ADC + adc_bcd <= D; + + default: adc_bcd <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0xxx_x110, // ASL, ROL, LSR, ROR (abs, absx, zpg, zpgx) + 8'b0xx0_1010: // ASL, ROL, LSR, ROR (acc) + shift <= 1; + + default: shift <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b1101_0010, // CMP (zp) + 8'b11x0_0x00, // CPX, CPY (imm/zp) + 8'b11x0_1100, // CPX, CPY (abs) + 8'b110x_xx01: // CMP + compare <= 1; + + default: compare <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b01xx_x110, // ROR, LSR + 8'b01xx_1x10: // ROR, LSR + shift_right <= 1; + + default: shift_right <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0x10_1010, // ROL A, ROR A + 8'b0x1x_x110: // ROR, ROL + rotate <= 1; + + default: rotate <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0000_x100: // TSB + op <= OP_OR; + + 8'b0001_x100: // TRB + op <= OP_AND; + + 8'b00xx_x110, // ROL, ASL + 8'b00x0_1010: // ROL, ASL + op <= OP_ROL; + + 8'b1000_1001, // BIT imm + 8'b001x_x100: // BIT zp/abs/zpx/absx + op <= OP_AND; + + 8'b01xx_x110, // ROR, LSR + 8'b01xx_1x10: // ROR, LSR + op <= OP_A; + + 8'b11x1_0010, // CMP, SBC (zp) + 8'b0011_1010, // DEC A + 8'b1000_1000, // DEY + 8'b1100_1010, // DEX + 8'b110x_x110, // DEC + 8'b11xx_xx01, // CMP, SBC + 8'b11x0_0x00, // CPX, CPY (imm, zpg) + 8'b11x0_1100: op <= OP_SUB; + + 8'b00x1_0010, // ORA, AND (zp) + 8'b0x01_0010, // ORA, EOR (zp) + 8'b010x_xx01, // EOR + 8'b00xx_xx01: // ORA, AND + op <= { 2'b11, IR[6:5] }; + + default: op <= OP_ADD; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b001x_x100: // BIT zp/abs/zpx/absx (update N,V,Z) + {bit_ins, bit_ins_nv} <= 2'b11; + + 8'b1000_1001: // BIT imm (update Z) + {bit_ins, bit_ins_nv} <= 2'b10; + + default: // not a BIT instruction + {bit_ins, bit_ins_nv} <= 2'b00; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b000x_x100: // TRB/TSB + txb_ins <= 1; + + default: txb_ins <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0001_x100: // TRB + trb_ins <= 1; + + default: trb_ins <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b1001_11x0, // STZ abs, STZ abs,x + 8'b011x_0100: // STZ zp, STZ zp,x + store_zero <= 1; + + default: store_zero <= 0; + endcase + +/* + * special instructions + */ +always @(posedge clk ) + if( state == DECODE && RDY ) begin + php <= (IR == 8'h08); + clc <= (IR == 8'h18); + plp <= (IR == 8'h28); + sec <= (IR == 8'h38); + cli <= (IR == 8'h58); + sei <= (IR == 8'h78); + clv <= (IR == 8'hb8); + cld <= (IR == 8'hd8); + sed <= (IR == 8'hf8); + end + +always @(posedge clk) + if( RDY ) + cond_code <= IR[7:4]; + +always @* + case( cond_code ) + 4'b0001: cond_true = ~N; + 4'b0011: cond_true = N; + 4'b0101: cond_true = ~V; + 4'b0111: cond_true = V; + 4'b1001: cond_true = ~C; + 4'b1011: cond_true = C; + 4'b1101: cond_true = ~Z; + 4'b1111: cond_true = Z; + default: cond_true = 1; // BRA is 80 + endcase + + +reg NMI_1 = 0; // delayed NMI signal + +always @(posedge clk) + NMI_1 <= NMI; + +always @(posedge clk ) + if( NMI_edge && state == BRK3 ) + NMI_edge <= 0; + else if( NMI & ~NMI_1 ) + NMI_edge <= 1; + +endmodule diff --git a/hw/efinix_fpga/simulation/timer_tb.sv b/hw/efinix_fpga/simulation/timer_tb.sv deleted file mode 100644 index 24d6cb2..0000000 --- a/hw/efinix_fpga/simulation/timer_tb.sv +++ /dev/null @@ -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 diff --git a/hw/efinix_fpga/simulation/verilog-6502 b/hw/efinix_fpga/simulation/verilog-6502 deleted file mode 160000 index a5f605d..0000000 --- a/hw/efinix_fpga/simulation/verilog-6502 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a5f605d00d22095532cc32aa7a481465b1bdca17 diff --git a/hw/efinix_fpga/src/sdram_adapter.sv b/hw/efinix_fpga/src/sdram_adapter.sv index c9c1603..f19f706 100644 --- a/hw/efinix_fpga/src/sdram_adapter.sv +++ b/hw/efinix_fpga/src/sdram_adapter.sv @@ -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 From 5e03795c0958a88e65f21bd100aac83f8d201757 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Thu, 21 Sep 2023 23:22:17 -0700 Subject: [PATCH 04/57] Get something simulated Infinite loop being caused somewhere --- hw/efinix_fpga/simulation/Makefile | 9 ++- hw/efinix_fpga/simulation/src/sim_top.sv | 93 +++++++++++++++++++++++- 2 files changed, 98 insertions(+), 4 deletions(-) diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index bd842ad..0385b34 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -8,10 +8,15 @@ INC=$(shell find include/ -type f) TOP_MODULE=sim_top TARGET=sim_top +INIT_MEM=init_hex.mem -all: +all: $(INIT_MEM) iverilog -g2005-sv -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS) +$(INIT_MEM): + cp ../$(INIT_MEM) . + .PHONY: clean clean: - rm -rf $(TARGET) \ No newline at end of file + rm -rf $(TARGET) + rm $(INIT_MEM) \ No newline at end of file diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index c20fa0f..6f45efe 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -1,10 +1,99 @@ +`timescale 1ns/1ps + module sim_top(); +logic r_sysclk, r_sdrclk, r_clk_50, r_clk_2; + +// clk_100 +initial begin + r_sysclk <= '0; + forever begin + #5 r_sysclk <= ~r_sysclk; + end +end + +// clk_200 +initial begin + r_sdrclk <= '0; + forever begin + #2.5 r_sdrclk <= ~r_sdrclk; + end +end + +// clk_50 +initial begin + r_clk_50 <= '0; + forever begin + #10 r_clk_50 <= ~r_clk_50; + end +end + +// clk_2 +initial begin + r_clk_2 <= '0; + 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(2000) @(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 cpu_rwb; + //TODO: this -cpu_65c02 u_cpu(); +cpu_65c02 u_cpu( + .clk(r_clk_2), + // .reset(~w_cpu_reset), + .reset(~button_reset), + .AB(w_cpu_addr), + .RDY('1), + .IRQ('0), + .NMI('0), + .DI(w_cpu_data_from_dut), + // .DO(w_cpu_data_from_cpu), + .WE(cpu_rwb) +); + + +// 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(); +// 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(~cpu_rwb) +// ); endmodule \ No newline at end of file From bc0ab7eb54fe24c89c07986c6b324671e7f9cc61 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Fri, 22 Sep 2023 19:46:25 -0700 Subject: [PATCH 05/57] Fix infinite loop --- hw/efinix_fpga/simulation/src/sim_top.sv | 36 ++++++++++++------------ hw/efinix_fpga/src/addr_decode.sv | 22 +++++++++------ hw/efinix_fpga/src/spi_controller.sv | 1 + hw/efinix_fpga/src/super6502.sv | 21 +++++++------- hw/efinix_fpga/src/timer.sv | 2 ++ 5 files changed, 44 insertions(+), 38 deletions(-) diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 6f45efe..703ba35 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -74,26 +74,26 @@ cpu_65c02 u_cpu( // 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) -); +// 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(~cpu_rwb) -// ); +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(~cpu_rwb) +); endmodule \ No newline at end of file diff --git a/hw/efinix_fpga/src/addr_decode.sv b/hw/efinix_fpga/src/addr_decode.sv index b137400..9a131fb 100644 --- a/hw/efinix_fpga/src/addr_decode.sv +++ b/hw/efinix_fpga/src/addr_decode.sv @@ -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; diff --git a/hw/efinix_fpga/src/spi_controller.sv b/hw/efinix_fpga/src/spi_controller.sv index 2d085e4..9f5c09d 100644 --- a/hw/efinix_fpga/src/spi_controller.sv +++ b/hw/efinix_fpga/src/spi_controller.sv @@ -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 diff --git a/hw/efinix_fpga/src/super6502.sv b/hw/efinix_fpga/src/super6502.sv index abe90d8..b0b1a49 100644 --- a/hw/efinix_fpga/src/super6502.sv +++ b/hw/efinix_fpga/src/super6502.sv @@ -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) diff --git a/hw/efinix_fpga/src/timer.sv b/hw/efinix_fpga/src/timer.sv index fa7f743..abebef9 100644 --- a/hw/efinix_fpga/src/timer.sv +++ b/hw/efinix_fpga/src/timer.sv @@ -123,6 +123,8 @@ always_comb begin o_data = status; end + default: o_data = 'x; + endcase end From 77dd4f100286ecb824d1f7f4c6baf4e0f4ce6e78 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sat, 23 Sep 2023 09:59:09 -0700 Subject: [PATCH 06/57] remove sim submodule --- .gitmodules | 5 +- .../simulation/src/verilog-6502/ALU.v | 108 -- .../simulation/src/verilog-6502/README.md | 69 - .../simulation/src/verilog-6502/cpu.v | 1220 -------------- .../simulation/src/verilog-6502/cpu_65c02.v | 1418 ----------------- 5 files changed, 1 insertion(+), 2819 deletions(-) delete mode 100755 hw/efinix_fpga/simulation/src/verilog-6502/ALU.v delete mode 100644 hw/efinix_fpga/simulation/src/verilog-6502/README.md delete mode 100644 hw/efinix_fpga/simulation/src/verilog-6502/cpu.v delete mode 100644 hw/efinix_fpga/simulation/src/verilog-6502/cpu_65c02.v diff --git a/.gitmodules b/.gitmodules index 6d2a279..591c898 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "sw/cc65"] path = sw/cc65 - url = https://git.byronlathi.com/bslathi19/cc65 -[submodule "hw/efinix_fpga/simulation/verilog-6502"] - path = hw/efinix_fpga/simulation/verilog-6502 - url = https://git.byronlathi.com/bslathi19/verilog-6502 + url = https://git.byronlathi.com/bslathi19/cc65 \ No newline at end of file diff --git a/hw/efinix_fpga/simulation/src/verilog-6502/ALU.v b/hw/efinix_fpga/simulation/src/verilog-6502/ALU.v deleted file mode 100755 index 8d05fc0..0000000 --- a/hw/efinix_fpga/simulation/src/verilog-6502/ALU.v +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ALU. - * - * AI and BI are 8 bit inputs. Result in OUT. - * CI is Carry In. - * CO is Carry Out. - * - * op[3:0] is defined as follows: - * - * 0011 AI + BI - * 0111 AI - BI - * 1011 AI + AI - * 1100 AI | BI - * 1101 AI & BI - * 1110 AI ^ BI - * 1111 AI - * - */ - -module ALU( clk, op, right, AI, BI, CI, CO, BCD, OUT, V, Z, N, HC, RDY ); - input clk; - input right; - input [3:0] op; // operation - input [7:0] AI; - input [7:0] BI; - input CI; - input BCD; // BCD style carry - output [7:0] OUT; - output CO; - output V; - output Z; - output N; - output HC; - input RDY; - -reg [7:0] OUT; -reg CO; -wire V; -wire Z; -reg N; -reg HC; - -reg AI7; -reg BI7; -reg [8:0] temp_logic; -reg [7:0] temp_BI; -reg [4:0] temp_l; -reg [4:0] temp_h; -wire [8:0] temp = { temp_h, temp_l[3:0] }; -wire adder_CI = (right | (op[3:2] == 2'b11)) ? 0 : CI; - -// calculate the logic operations. The 'case' can be done in 1 LUT per -// bit. The 'right' shift is a simple mux that can be implemented by -// F5MUX. -always @* begin - case( op[1:0] ) - 2'b00: temp_logic = AI | BI; - 2'b01: temp_logic = AI & BI; - 2'b10: temp_logic = AI ^ BI; - 2'b11: temp_logic = AI; - endcase - - if( right ) - temp_logic = { AI[0], CI, AI[7:1] }; -end - -// Add logic result to BI input. This only makes sense when logic = AI. -// This stage can be done in 1 LUT per bit, using carry chain logic. -always @* begin - case( op[3:2] ) - 2'b00: temp_BI = BI; // A+B - 2'b01: temp_BI = ~BI; // A-B - 2'b10: temp_BI = temp_logic; // A+A - 2'b11: temp_BI = 0; // A+0 - endcase -end - -// HC9 is the half carry bit when doing BCD add -wire HC9 = BCD & (temp_l[3:1] >= 3'd5); - -// CO9 is the carry-out bit when doing BCD add -wire CO9 = BCD & (temp_h[3:1] >= 3'd5); - -// combined half carry bit -wire temp_HC = temp_l[4] | HC9; - -// perform the addition as 2 separate nibble, so we get -// access to the half carry flag -always @* begin - temp_l = temp_logic[3:0] + temp_BI[3:0] + adder_CI; - temp_h = temp_logic[8:4] + temp_BI[7:4] + temp_HC; -end - -// calculate the flags -always @(posedge clk) - if( RDY ) begin - AI7 <= AI[7]; - BI7 <= temp_BI[7]; - OUT <= temp[7:0]; - CO <= temp[8] | CO9; - N <= temp[7]; - HC <= temp_HC; - end - -assign V = AI7 ^ BI7 ^ CO ^ N; -assign Z = ~|OUT; - -endmodule diff --git a/hw/efinix_fpga/simulation/src/verilog-6502/README.md b/hw/efinix_fpga/simulation/src/verilog-6502/README.md deleted file mode 100644 index 42e6ad6..0000000 --- a/hw/efinix_fpga/simulation/src/verilog-6502/README.md +++ /dev/null @@ -1,69 +0,0 @@ -======================================================== -A Verilog HDL version of the old MOS 6502 and 65C02 CPUs -======================================================== - -Original 6502 core by Arlet Ottens - -65C02 extensions by David Banks and Ed Spittles - -========== -6502 Core -========== - -Arlet's original 6502 core (cpu.v) is unchanged. - -Note: the 6502/65C02 cores assumes a synchronous memory. This means -that valid data (DI) is expected on the cycle *after* valid -address. This allows direct connection to (Xilinx) block RAMs. When -using asynchronous memory, I suggest registering the address/control -lines for glitchless output signals. - -[Also check out my new 65C02 project](https://github.com/Arlet/verilog-65c02) - -Have fun. - -========== -65C02 Core -========== - -A second core (cpu_65c02.v) has been added, based on Arlet's 6502 -core, with additional 65C02 instructions and addressing modes: -- PHX, PHY, PLX, PLY -- BRA -- INC A, DEC A -- (zp) addressing mode -- STZ -- BIT zpx, absx, imm -- TSB/TRB -- JMP (,X) -- NOPs (optional) -- 65C02 BCD N/Z flags (optional, disabled) - -The Rockwell/WDC specific instructions (RMB/SMB/BBR/BBS/WAI/STP) are -not currently implemented - -The 65C02 core passes the Dormann 6502 test suite, and also passes the -Dormann 65C02 test suite if the optional support for NOPs and 65C02 -BCD flags is enabled. - -It has been tested as a BBC Micro "Matchbox" 65C02 Co Processor, in a -XC6SLX9-2 FPGA, running at 80MHz using 64KB of internel block RAM. It -just meets timing at 80MHz in this environment. It successfully runs -BBC Basic IV and Tube Elite. - -============ -Known Issues -============ - -The Matchbox Co Processor needed one wait state (via RDY) to be added -to each ROM access (only needed early in the boot process, as -eventually everything runs from RAM). The DIHOLD logic did not work -correctly with a single wait state, and so has been commented out. - -I now believe the correct fix is actually just: - -always @(posedge clk ) - if( RDY ) - DIHOLD <= DI; - -assign DIMUX = ~RDY ? DIHOLD : DI; diff --git a/hw/efinix_fpga/simulation/src/verilog-6502/cpu.v b/hw/efinix_fpga/simulation/src/verilog-6502/cpu.v deleted file mode 100644 index ed8da62..0000000 --- a/hw/efinix_fpga/simulation/src/verilog-6502/cpu.v +++ /dev/null @@ -1,1220 +0,0 @@ -/* - * verilog model of 6502 CPU. - * - * (C) Arlet Ottens, - * - * Feel free to use this code in any project (commercial or not), as long as you - * keep this message, and the copyright notice. This code is provided "as is", - * without any warranties of any kind. - * - */ - -/* - * Note that not all 6502 interface signals are supported (yet). The goal - * is to create an Acorn Atom model, and the Atom didn't use all signals on - * the main board. - * - * The data bus is implemented as separate read/write buses. Combine them - * on the output pads if external memory is required. - */ - -module cpu( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY ); - -input clk; // CPU clock -input reset; // reset signal -output reg [15:0] AB; // address bus -input [7:0] DI; // data in, read bus -output [7:0] DO; // data out, write bus -output WE; // write enable -input IRQ; // interrupt request -input NMI; // non-maskable interrupt request -input RDY; // Ready signal. Pauses CPU when RDY=0 - -/* - * internal signals - */ - -reg [15:0] PC; // Program Counter -reg [7:0] ABL; // Address Bus Register LSB -reg [7:0] ABH; // Address Bus Register MSB -wire [7:0] ADD; // Adder Hold Register (registered in ALU) - -reg [7:0] DIHOLD; // Hold for Data In -reg DIHOLD_valid; // -wire [7:0] DIMUX; // - -reg [7:0] IRHOLD; // Hold for Instruction register -reg IRHOLD_valid; // Valid instruction in IRHOLD - -reg [7:0] AXYS[3:0]; // A, X, Y and S register file - -reg C = 0; // carry flag (init at zero to avoid X's in ALU sim) -reg Z = 0; // zero flag -reg I = 0; // interrupt flag -reg D = 0; // decimal flag -reg V = 0; // overflow flag -reg N = 0; // negative flag -wire AZ; // ALU Zero flag -wire AV; // ALU overflow flag -wire AN; // ALU negative flag -wire HC; // ALU half carry - -reg [7:0] AI; // ALU Input A -reg [7:0] BI; // ALU Input B -wire [7:0] DI; // Data In -wire [7:0] IR; // Instruction register -reg [7:0] DO; // Data Out -reg WE; // Write Enable -reg CI; // Carry In -wire CO; // Carry Out -wire [7:0] PCH = PC[15:8]; -wire [7:0] PCL = PC[7:0]; - -reg NMI_edge = 0; // captured NMI edge - -reg [1:0] regsel; // Select A, X, Y or S register -wire [7:0] regfile = AXYS[regsel]; // Selected register output - -parameter - SEL_A = 2'd0, - SEL_S = 2'd1, - SEL_X = 2'd2, - SEL_Y = 2'd3; - -/* - * define some signals for watching in simulator output - */ - - -`ifdef SIM -wire [7:0] A = AXYS[SEL_A]; // Accumulator -wire [7:0] X = AXYS[SEL_X]; // X register -wire [7:0] Y = AXYS[SEL_Y]; // Y register -wire [7:0] S = AXYS[SEL_S]; // Stack pointer -`endif - -wire [7:0] P = { N, V, 2'b11, D, I, Z, C }; - -/* - * instruction decoder/sequencer - */ - -reg [5:0] state; - -/* - * control signals - */ - -reg PC_inc; // Increment PC -reg [15:0] PC_temp; // intermediate value of PC - -reg [1:0] src_reg; // source register index -reg [1:0] dst_reg; // destination register index - -reg index_y; // if set, then Y is index reg rather than X -reg load_reg; // loading a register (A, X, Y, S) in this instruction -reg inc; // increment -reg write_back; // set if memory is read/modified/written -reg load_only; // LDA/LDX/LDY instruction -reg store; // doing store (STA/STX/STY) -reg adc_sbc; // doing ADC/SBC -reg compare; // doing CMP/CPY/CPX -reg shift; // doing shift/rotate instruction -reg rotate; // doing rotate (no shift) -reg backwards; // backwards branch -reg cond_true; // branch condition is true -reg [2:0] cond_code; // condition code bits from instruction -reg shift_right; // Instruction ALU shift/rotate right -reg alu_shift_right; // Current cycle shift right enable -reg [3:0] op; // Main ALU operation for instruction -reg [3:0] alu_op; // Current cycle ALU operation -reg adc_bcd; // ALU should do BCD style carry -reg adj_bcd; // results should be BCD adjusted - -/* - * some flip flops to remember we're doing special instructions. These - * get loaded at the DECODE state, and used later - */ -reg bit_ins; // doing BIT instruction -reg plp; // doing PLP instruction -reg php; // doing PHP instruction -reg clc; // clear carry -reg sec; // set carry -reg cld; // clear decimal -reg sed; // set decimal -reg cli; // clear interrupt -reg sei; // set interrupt -reg clv; // clear overflow -reg brk; // doing BRK - -reg res; // in reset - -/* - * ALU operations - */ - -parameter - OP_OR = 4'b1100, - OP_AND = 4'b1101, - OP_EOR = 4'b1110, - OP_ADD = 4'b0011, - OP_SUB = 4'b0111, - OP_ROL = 4'b1011, - OP_A = 4'b1111; - -/* - * Microcode state machine. Basically, every addressing mode has its own - * path through the state machine. Additional information, such as the - * operation, source and destination registers are decoded in parallel, and - * kept in separate flops. - */ - -parameter - ABS0 = 6'd0, // ABS - fetch LSB - ABS1 = 6'd1, // ABS - fetch MSB - ABSX0 = 6'd2, // ABS, X - fetch LSB and send to ALU (+X) - ABSX1 = 6'd3, // ABS, X - fetch MSB and send to ALU (+Carry) - ABSX2 = 6'd4, // ABS, X - Wait for ALU (only if needed) - BRA0 = 6'd5, // Branch - fetch offset and send to ALU (+PC[7:0]) - BRA1 = 6'd6, // Branch - fetch opcode, and send PC[15:8] to ALU - BRA2 = 6'd7, // Branch - fetch opcode (if page boundary crossed) - BRK0 = 6'd8, // BRK/IRQ - push PCH, send S to ALU (-1) - BRK1 = 6'd9, // BRK/IRQ - push PCL, send S to ALU (-1) - BRK2 = 6'd10, // BRK/IRQ - push P, send S to ALU (-1) - BRK3 = 6'd11, // BRK/IRQ - write S, and fetch @ fffe - DECODE = 6'd12, // IR is valid, decode instruction, and write prev reg - FETCH = 6'd13, // fetch next opcode, and perform prev ALU op - INDX0 = 6'd14, // (ZP,X) - fetch ZP address, and send to ALU (+X) - INDX1 = 6'd15, // (ZP,X) - fetch LSB at ZP+X, calculate ZP+X+1 - INDX2 = 6'd16, // (ZP,X) - fetch MSB at ZP+X+1 - INDX3 = 6'd17, // (ZP,X) - fetch data - INDY0 = 6'd18, // (ZP),Y - fetch ZP address, and send ZP to ALU (+1) - INDY1 = 6'd19, // (ZP),Y - fetch at ZP+1, and send LSB to ALU (+Y) - INDY2 = 6'd20, // (ZP),Y - fetch data, and send MSB to ALU (+Carry) - INDY3 = 6'd21, // (ZP),Y) - fetch data (if page boundary crossed) - JMP0 = 6'd22, // JMP - fetch PCL and hold - JMP1 = 6'd23, // JMP - fetch PCH - JMPI0 = 6'd24, // JMP IND - fetch LSB and send to ALU for delay (+0) - JMPI1 = 6'd25, // JMP IND - fetch MSB, proceed with JMP0 state - JSR0 = 6'd26, // JSR - push PCH, save LSB, send S to ALU (-1) - JSR1 = 6'd27, // JSR - push PCL, send S to ALU (-1) - JSR2 = 6'd28, // JSR - write S - JSR3 = 6'd29, // JSR - fetch MSB - PULL0 = 6'd30, // PLP/PLA - save next op in IRHOLD, send S to ALU (+1) - PULL1 = 6'd31, // PLP/PLA - fetch data from stack, write S - PULL2 = 6'd32, // PLP/PLA - prefetch op, but don't increment PC - PUSH0 = 6'd33, // PHP/PHA - send A to ALU (+0) - PUSH1 = 6'd34, // PHP/PHA - write A/P, send S to ALU (-1) - READ = 6'd35, // Read memory for read/modify/write (INC, DEC, shift) - REG = 6'd36, // Read register for reg-reg transfers - RTI0 = 6'd37, // RTI - send S to ALU (+1) - RTI1 = 6'd38, // RTI - read P from stack - RTI2 = 6'd39, // RTI - read PCL from stack - RTI3 = 6'd40, // RTI - read PCH from stack - RTI4 = 6'd41, // RTI - read PCH from stack - RTS0 = 6'd42, // RTS - send S to ALU (+1) - RTS1 = 6'd43, // RTS - read PCL from stack - RTS2 = 6'd44, // RTS - write PCL to ALU, read PCH - RTS3 = 6'd45, // RTS - load PC and increment - WRITE = 6'd46, // Write memory for read/modify/write - ZP0 = 6'd47, // Z-page - fetch ZP address - ZPX0 = 6'd48, // ZP, X - fetch ZP, and send to ALU (+X) - ZPX1 = 6'd49; // ZP, X - load from memory - -`ifdef SIM - -/* - * easy to read names in simulator output - */ -reg [8*6-1:0] statename; - -always @* - case( state ) - DECODE: statename = "DECODE"; - REG: statename = "REG"; - ZP0: statename = "ZP0"; - ZPX0: statename = "ZPX0"; - ZPX1: statename = "ZPX1"; - ABS0: statename = "ABS0"; - ABS1: statename = "ABS1"; - ABSX0: statename = "ABSX0"; - ABSX1: statename = "ABSX1"; - ABSX2: statename = "ABSX2"; - INDX0: statename = "INDX0"; - INDX1: statename = "INDX1"; - INDX2: statename = "INDX2"; - INDX3: statename = "INDX3"; - INDY0: statename = "INDY0"; - INDY1: statename = "INDY1"; - INDY2: statename = "INDY2"; - INDY3: statename = "INDY3"; - READ: statename = "READ"; - WRITE: statename = "WRITE"; - FETCH: statename = "FETCH"; - PUSH0: statename = "PUSH0"; - PUSH1: statename = "PUSH1"; - PULL0: statename = "PULL0"; - PULL1: statename = "PULL1"; - PULL2: statename = "PULL2"; - JSR0: statename = "JSR0"; - JSR1: statename = "JSR1"; - JSR2: statename = "JSR2"; - JSR3: statename = "JSR3"; - RTI0: statename = "RTI0"; - RTI1: statename = "RTI1"; - RTI2: statename = "RTI2"; - RTI3: statename = "RTI3"; - RTI4: statename = "RTI4"; - RTS0: statename = "RTS0"; - RTS1: statename = "RTS1"; - RTS2: statename = "RTS2"; - RTS3: statename = "RTS3"; - BRK0: statename = "BRK0"; - BRK1: statename = "BRK1"; - BRK2: statename = "BRK2"; - BRK3: statename = "BRK3"; - BRA0: statename = "BRA0"; - BRA1: statename = "BRA1"; - BRA2: statename = "BRA2"; - JMP0: statename = "JMP0"; - JMP1: statename = "JMP1"; - JMPI0: statename = "JMPI0"; - JMPI1: statename = "JMPI1"; - endcase - -//always @( PC ) -// $display( "%t, PC:%04x IR:%02x A:%02x X:%02x Y:%02x S:%02x C:%d Z:%d V:%d N:%d P:%02x", $time, PC, IR, A, X, Y, S, C, Z, V, N, P ); - -`endif - - - -/* - * Program Counter Increment/Load. First calculate the base value in - * PC_temp. - */ -always @* - case( state ) - DECODE: if( (~I & IRQ) | NMI_edge ) - PC_temp = { ABH, ABL }; - else - PC_temp = PC; - - - JMP1, - JMPI1, - JSR3, - RTS3, - RTI4: PC_temp = { DIMUX, ADD }; - - BRA1: PC_temp = { ABH, ADD }; - - BRA2: PC_temp = { ADD, PCL }; - - BRK2: PC_temp = res ? 16'hfffc : - NMI_edge ? 16'hfffa : 16'hfffe; - - default: PC_temp = PC; - endcase - -/* - * Determine wether we need PC_temp, or PC_temp + 1 - */ -always @* - case( state ) - DECODE: if( (~I & IRQ) | NMI_edge ) - PC_inc = 0; - else - PC_inc = 1; - - ABS0, - ABSX0, - FETCH, - BRA0, - BRA2, - BRK3, - JMPI1, - JMP1, - RTI4, - RTS3: PC_inc = 1; - - BRA1: PC_inc = CO ^~ backwards; - - default: PC_inc = 0; - endcase - -/* - * Set new PC - */ -always @(posedge clk) - if( RDY ) - PC <= PC_temp + PC_inc; - -/* - * Address Generator - */ - -parameter - ZEROPAGE = 8'h00, - STACKPAGE = 8'h01; - -always @* - case( state ) - ABSX1, - INDX3, - INDY2, - JMP1, - JMPI1, - RTI4, - ABS1: AB = { DIMUX, ADD }; - - BRA2, - INDY3, - ABSX2: AB = { ADD, ABL }; - - BRA1: AB = { ABH, ADD }; - - JSR0, - PUSH1, - RTS0, - RTI0, - BRK0: AB = { STACKPAGE, regfile }; - - BRK1, - JSR1, - PULL1, - RTS1, - RTS2, - RTI1, - RTI2, - RTI3, - BRK2: AB = { STACKPAGE, ADD }; - - INDY1, - INDX1, - ZPX1, - INDX2: AB = { ZEROPAGE, ADD }; - - ZP0, - INDY0: AB = { ZEROPAGE, DIMUX }; - - REG, - READ, - WRITE: AB = { ABH, ABL }; - - default: AB = PC; - endcase - -/* - * ABH/ABL pair is used for registering previous address bus state. - * This can be used to keep the current address, freeing up the original - * source of the address, such as the ALU or DI. - */ -always @(posedge clk) - if( state != PUSH0 && state != PUSH1 && RDY && - state != PULL0 && state != PULL1 && state != PULL2 ) - begin - ABL <= AB[7:0]; - ABH <= AB[15:8]; - end - -/* - * Data Out MUX - */ -always @* - case( state ) - WRITE: DO = ADD; - - JSR0, - BRK0: DO = PCH; - - JSR1, - BRK1: DO = PCL; - - PUSH1: DO = php ? P : ADD; - - BRK2: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P; - - default: DO = regfile; - endcase - -/* - * Write Enable Generator - */ - -always @* - case( state ) - BRK0, // writing to stack or memory - BRK1, - BRK2, - JSR0, - JSR1, - PUSH1, - WRITE: WE = 1; - - INDX3, // only if doing a STA, STX or STY - INDY3, - ABSX2, - ABS1, - ZPX1, - ZP0: WE = store; - - default: WE = 0; - endcase - -/* - * register file, contains A, X, Y and S (stack pointer) registers. At each - * cycle only 1 of those registers needs to be accessed, so they combined - * in a small memory, saving resources. - */ - -reg write_register; // set when register file is written - -always @* - case( state ) - DECODE: write_register = load_reg & ~plp; - - PULL1, - RTS2, - RTI3, - BRK3, - JSR0, - JSR2 : write_register = 1; - - default: write_register = 0; - endcase - -/* - * BCD adjust logic - */ - -always @(posedge clk) - adj_bcd <= adc_sbc & D; // '1' when doing a BCD instruction - -reg [3:0] ADJL; -reg [3:0] ADJH; - -// adjustment term to be added to ADD[3:0] based on the following -// adj_bcd: '1' if doing ADC/SBC with D=1 -// adc_bcd: '1' if doing ADC with D=1 -// HC : half carry bit from ALU -always @* begin - casex( {adj_bcd, adc_bcd, HC} ) - 3'b0xx: ADJL = 4'd0; // no BCD instruction - 3'b100: ADJL = 4'd10; // SBC, and digital borrow - 3'b101: ADJL = 4'd0; // SBC, but no borrow - 3'b110: ADJL = 4'd0; // ADC, but no carry - 3'b111: ADJL = 4'd6; // ADC, and decimal/digital carry - endcase -end - -// adjustment term to be added to ADD[7:4] based on the following -// adj_bcd: '1' if doing ADC/SBC with D=1 -// adc_bcd: '1' if doing ADC with D=1 -// CO : carry out bit from ALU -always @* begin - casex( {adj_bcd, adc_bcd, CO} ) - 3'b0xx: ADJH = 4'd0; // no BCD instruction - 3'b100: ADJH = 4'd10; // SBC, and digital borrow - 3'b101: ADJH = 4'd0; // SBC, but no borrow - 3'b110: ADJH = 4'd0; // ADC, but no carry - 3'b111: ADJH = 4'd6; // ADC, and decimal/digital carry - endcase -end - -/* - * write to a register. Usually this is the (BCD corrected) output of the - * ALU, but in case of the JSR0 we use the S register to temporarily store - * the PCL. This is possible, because the S register itself is stored in - * the ALU during those cycles. - */ -always @(posedge clk) - if( write_register & RDY ) - AXYS[regsel] <= (state == JSR0) ? DIMUX : { ADD[7:4] + ADJH, ADD[3:0] + ADJL }; - -/* - * register select logic. This determines which of the A, X, Y or - * S registers will be accessed. - */ - -always @* - case( state ) - INDY1, - INDX0, - ZPX0, - ABSX0 : regsel = index_y ? SEL_Y : SEL_X; - - - DECODE : regsel = dst_reg; - - BRK0, - BRK3, - JSR0, - JSR2, - PULL0, - PULL1, - PUSH1, - RTI0, - RTI3, - RTS0, - RTS2 : regsel = SEL_S; - - default: regsel = src_reg; - endcase - -/* - * ALU - */ - -ALU ALU( .clk(clk), - .op(alu_op), - .right(alu_shift_right), - .AI(AI), - .BI(BI), - .CI(CI), - .BCD(adc_bcd & (state == FETCH)), - .CO(CO), - .OUT(ADD), - .V(AV), - .Z(AZ), - .N(AN), - .HC(HC), - .RDY(RDY) ); - -/* - * Select current ALU operation - */ - -always @* - case( state ) - READ: alu_op = op; - - BRA1: alu_op = backwards ? OP_SUB : OP_ADD; - - FETCH, - REG : alu_op = op; - - DECODE, - ABS1: alu_op = 1'bx; - - PUSH1, - BRK0, - BRK1, - BRK2, - JSR0, - JSR1: alu_op = OP_SUB; - - default: alu_op = OP_ADD; - endcase - -/* - * Determine shift right signal to ALU - */ - -always @* - if( state == FETCH || state == REG || state == READ ) - alu_shift_right = shift_right; - else - alu_shift_right = 0; - -/* - * Sign extend branch offset. - */ - -always @(posedge clk) - if( RDY ) - backwards <= DIMUX[7]; - -/* - * ALU A Input MUX - */ - -always @* - case( state ) - JSR1, - RTS1, - RTI1, - RTI2, - BRK1, - BRK2, - INDX1: AI = ADD; - - REG, - ZPX0, - INDX0, - ABSX0, - RTI0, - RTS0, - JSR0, - JSR2, - BRK0, - PULL0, - INDY1, - PUSH0, - PUSH1: AI = regfile; - - BRA0, - READ: AI = DIMUX; - - BRA1: AI = ABH; // don't use PCH in case we're - - FETCH: AI = load_only ? 0 : regfile; - - DECODE, - ABS1: AI = 8'hxx; // don't care - - default: AI = 0; - endcase - - -/* - * ALU B Input mux - */ - -always @* - case( state ) - BRA1, - RTS1, - RTI0, - RTI1, - RTI2, - INDX1, - READ, - REG, - JSR0, - JSR1, - JSR2, - BRK0, - BRK1, - BRK2, - PUSH0, - PUSH1, - PULL0, - RTS0: BI = 8'h00; - - BRA0: BI = PCL; - - DECODE, - ABS1: BI = 8'hxx; - - default: BI = DIMUX; - endcase - -/* - * ALU CI (carry in) mux - */ - -always @* - case( state ) - INDY2, - BRA1, - ABSX1: CI = CO; - - DECODE, - ABS1: CI = 1'bx; - - READ, - REG: CI = rotate ? C : - shift ? 0 : inc; - - FETCH: CI = rotate ? C : - compare ? 1 : - (shift | load_only) ? 0 : C; - - PULL0, - RTI0, - RTI1, - RTI2, - RTS0, - RTS1, - INDY0, - INDX1: CI = 1; - - default: CI = 0; - endcase - -/* - * Processor Status Register update - * - */ - -/* - * Update C flag when doing ADC/SBC, shift/rotate, compare - */ -always @(posedge clk ) - if( shift && state == WRITE ) - C <= CO; - else if( state == RTI2 ) - C <= DIMUX[0]; - else if( ~write_back && state == DECODE ) begin - if( adc_sbc | shift | compare ) - C <= CO; - else if( plp ) - C <= ADD[0]; - else begin - if( sec ) C <= 1; - if( clc ) C <= 0; - end - end - -/* - * Update Z, N flags when writing A, X, Y, Memory, or when doing compare - */ - -always @(posedge clk) - if( state == WRITE ) - Z <= AZ; - else if( state == RTI2 ) - Z <= DIMUX[1]; - else if( state == DECODE ) begin - if( plp ) - Z <= ADD[1]; - else if( (load_reg & (regsel != SEL_S)) | compare | bit_ins ) - Z <= AZ; - end - -always @(posedge clk) - if( state == WRITE ) - N <= AN; - else if( state == RTI2 ) - N <= DIMUX[7]; - else if( state == DECODE ) begin - if( plp ) - N <= ADD[7]; - else if( (load_reg & (regsel != SEL_S)) | compare ) - N <= AN; - end else if( state == FETCH && bit_ins ) - N <= DIMUX[7]; - -/* - * Update I flag - */ - -always @(posedge clk) - if( state == BRK3 ) - I <= 1; - else if( state == RTI2 ) - I <= DIMUX[2]; - else if( state == REG ) begin - if( sei ) I <= 1; - if( cli ) I <= 0; - end else if( state == DECODE ) - if( plp ) I <= ADD[2]; - -/* - * Update D flag - */ -always @(posedge clk ) - if( state == RTI2 ) - D <= DIMUX[3]; - else if( state == DECODE ) begin - if( sed ) D <= 1; - if( cld ) D <= 0; - if( plp ) D <= ADD[3]; - end - -/* - * Update V flag - */ -always @(posedge clk ) - if( state == RTI2 ) - V <= DIMUX[6]; - else if( state == DECODE ) begin - if( adc_sbc ) V <= AV; - if( clv ) V <= 0; - if( plp ) V <= ADD[6]; - end else if( state == FETCH && bit_ins ) - V <= DIMUX[6]; - -/* - * Instruction decoder - */ - -/* - * IR register/mux. Hold previous DI value in IRHOLD in PULL0 and PUSH0 - * states. In these states, the IR has been prefetched, and there is no - * time to read the IR again before the next decode. - */ - -always @(posedge clk ) - if( reset ) - IRHOLD_valid <= 0; - else if( RDY ) begin - if( state == PULL0 || state == PUSH0 ) begin - IRHOLD <= DIMUX; - IRHOLD_valid <= 1; - end else if( state == DECODE ) - IRHOLD_valid <= 0; - end - -assign IR = (IRQ & ~I) | NMI_edge ? 8'h00 : - IRHOLD_valid ? IRHOLD : DIMUX; - -always @(posedge clk ) - if( RDY ) - DIHOLD <= DI; - -assign DIMUX = ~RDY ? DIHOLD : DI; - -/* - * Microcode state machine - */ -always @(posedge clk or posedge reset) - if( reset ) - state <= BRK0; - else if( RDY ) case( state ) - DECODE : - casex ( IR ) - 8'b0000_0000: state <= BRK0; - 8'b0010_0000: state <= JSR0; - 8'b0010_1100: state <= ABS0; // BIT abs - 8'b0100_0000: state <= RTI0; // - 8'b0100_1100: state <= JMP0; - 8'b0110_0000: state <= RTS0; - 8'b0110_1100: state <= JMPI0; - 8'b0x00_1000: state <= PUSH0; - 8'b0x10_1000: state <= PULL0; - 8'b0xx1_1000: state <= REG; // CLC, SEC, CLI, SEI - 8'b1xx0_00x0: state <= FETCH; // IMM - 8'b1xx0_1100: state <= ABS0; // X/Y abs - 8'b1xxx_1000: state <= REG; // DEY, TYA, ... - 8'bxxx0_0001: state <= INDX0; - 8'bxxx0_01xx: state <= ZP0; - 8'bxxx0_1001: state <= FETCH; // IMM - 8'bxxx0_1101: state <= ABS0; // even E column - 8'bxxx0_1110: state <= ABS0; // even E column - 8'bxxx1_0000: state <= BRA0; // odd 0 column - 8'bxxx1_0001: state <= INDY0; // odd 1 column - 8'bxxx1_01xx: state <= ZPX0; // odd 4,5,6,7 columns - 8'bxxx1_1001: state <= ABSX0; // odd 9 column - 8'bxxx1_11xx: state <= ABSX0; // odd C, D, E, F columns - 8'bxxxx_1010: state <= REG; // A, TXA, ... NOP - endcase - - ZP0 : state <= write_back ? READ : FETCH; - - ZPX0 : state <= ZPX1; - ZPX1 : state <= write_back ? READ : FETCH; - - ABS0 : state <= ABS1; - ABS1 : state <= write_back ? READ : FETCH; - - ABSX0 : state <= ABSX1; - ABSX1 : state <= (CO | store | write_back) ? ABSX2 : FETCH; - ABSX2 : state <= write_back ? READ : FETCH; - - INDX0 : state <= INDX1; - INDX1 : state <= INDX2; - INDX2 : state <= INDX3; - INDX3 : state <= FETCH; - - INDY0 : state <= INDY1; - INDY1 : state <= INDY2; - INDY2 : state <= (CO | store) ? INDY3 : FETCH; - INDY3 : state <= FETCH; - - READ : state <= WRITE; - WRITE : state <= FETCH; - FETCH : state <= DECODE; - - REG : state <= DECODE; - - PUSH0 : state <= PUSH1; - PUSH1 : state <= DECODE; - - PULL0 : state <= PULL1; - PULL1 : state <= PULL2; - PULL2 : state <= DECODE; - - JSR0 : state <= JSR1; - JSR1 : state <= JSR2; - JSR2 : state <= JSR3; - JSR3 : state <= FETCH; - - RTI0 : state <= RTI1; - RTI1 : state <= RTI2; - RTI2 : state <= RTI3; - RTI3 : state <= RTI4; - RTI4 : state <= DECODE; - - RTS0 : state <= RTS1; - RTS1 : state <= RTS2; - RTS2 : state <= RTS3; - RTS3 : state <= FETCH; - - BRA0 : state <= cond_true ? BRA1 : DECODE; - BRA1 : state <= (CO ^ backwards) ? BRA2 : DECODE; - BRA2 : state <= DECODE; - - JMP0 : state <= JMP1; - JMP1 : state <= DECODE; - - JMPI0 : state <= JMPI1; - JMPI1 : state <= JMP0; - - BRK0 : state <= BRK1; - BRK1 : state <= BRK2; - BRK2 : state <= BRK3; - BRK3 : state <= JMP0; - - endcase - -/* - * Additional control signals - */ - -always @(posedge clk) - if( reset ) - res <= 1; - else if( state == DECODE ) - res <= 0; - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0xx01010, // ASLA, ROLA, LSRA, RORA - 8'b0xxxxx01, // ORA, AND, EOR, ADC - 8'b100x10x0, // DEY, TYA, TXA, TXS - 8'b1010xxx0, // LDA/LDX/LDY - 8'b10111010, // TSX - 8'b1011x1x0, // LDX/LDY - 8'b11001010, // DEX - 8'b1x1xxx01, // LDA, SBC - 8'bxxx01000: // DEY, TAY, INY, INX - load_reg <= 1; - - default: load_reg <= 0; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1110_1000, // INX - 8'b1100_1010, // DEX - 8'b101x_xx10: // LDX, TAX, TSX - dst_reg <= SEL_X; - - 8'b0x00_1000, // PHP, PHA - 8'b1001_1010: // TXS - dst_reg <= SEL_S; - - 8'b1x00_1000, // DEY, DEX - 8'b101x_x100, // LDY - 8'b1010_x000: // LDY #imm, TAY - dst_reg <= SEL_Y; - - default: dst_reg <= SEL_A; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1011_1010: // TSX - src_reg <= SEL_S; - - 8'b100x_x110, // STX - 8'b100x_1x10, // TXA, TXS - 8'b1110_xx00, // INX, CPX - 8'b1100_1010: // DEX - src_reg <= SEL_X; - - 8'b100x_x100, // STY - 8'b1001_1000, // TYA - 8'b1100_xx00, // CPY - 8'b1x00_1000: // DEY, INY - src_reg <= SEL_Y; - - default: src_reg <= SEL_A; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'bxxx1_0001, // INDY - 8'b10x1_x110, // LDX/STX zpg/abs, Y - 8'bxxxx_1001: // abs, Y - index_y <= 1; - - default: index_y <= 0; - endcase - - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b100x_x1x0, // STX, STY - 8'b100x_xx01: // STA - store <= 1; - - default: store <= 0; - - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0xxx_x110, // ASL, ROL, LSR, ROR - 8'b11xx_x110: // DEC/INC - write_back <= 1; - - default: write_back <= 0; - endcase - - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b101x_xxxx: // LDA, LDX, LDY - load_only <= 1; - default: load_only <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b111x_x110, // INC - 8'b11x0_1000: // INX, INY - inc <= 1; - - default: inc <= 0; - endcase - -always @(posedge clk ) - if( (state == DECODE || state == BRK0) && RDY ) - casex( IR ) - 8'bx11x_xx01: // SBC, ADC - adc_sbc <= 1; - - default: adc_sbc <= 0; - endcase - -always @(posedge clk ) - if( (state == DECODE || state == BRK0) && RDY ) - casex( IR ) - 8'b011x_xx01: // ADC - adc_bcd <= D; - - default: adc_bcd <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0xxx_x110, // ASL, ROL, LSR, ROR (abs, absx, zpg, zpgx) - 8'b0xxx_1010: // ASL, ROL, LSR, ROR (acc) - shift <= 1; - - default: shift <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b11x0_0x00, // CPX, CPY (imm/zp) - 8'b11x0_1100, // CPX, CPY (abs) - 8'b110x_xx01: // CMP - compare <= 1; - - default: compare <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b01xx_xx10: // ROR, LSR - shift_right <= 1; - - default: shift_right <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0x1x_1010, // ROL A, ROR A - 8'b0x1x_x110: // ROR, ROL - rotate <= 1; - - default: rotate <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b00xx_xx10: // ROL, ASL - op <= OP_ROL; - - 8'b0010_x100: // BIT zp/abs - op <= OP_AND; - - 8'b01xx_xx10: // ROR, LSR - op <= OP_A; - - 8'b1000_1000, // DEY - 8'b1100_1010, // DEX - 8'b110x_x110, // DEC - 8'b11xx_xx01, // CMP, SBC - 8'b11x0_0x00, // CPX, CPY (imm, zpg) - 8'b11x0_1100: op <= OP_SUB; - - 8'b010x_xx01, // EOR - 8'b00xx_xx01: // ORA, AND - op <= { 2'b11, IR[6:5] }; - - default: op <= OP_ADD; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0010_x100: // BIT zp/abs - bit_ins <= 1; - - default: bit_ins <= 0; - endcase - -/* - * special instructions - */ -always @(posedge clk ) - if( state == DECODE && RDY ) begin - php <= (IR == 8'h08); - clc <= (IR == 8'h18); - plp <= (IR == 8'h28); - sec <= (IR == 8'h38); - cli <= (IR == 8'h58); - sei <= (IR == 8'h78); - clv <= (IR == 8'hb8); - cld <= (IR == 8'hd8); - sed <= (IR == 8'hf8); - brk <= (IR == 8'h00); - end - -always @(posedge clk) - if( RDY ) - cond_code <= IR[7:5]; - -always @* - case( cond_code ) - 3'b000: cond_true = ~N; - 3'b001: cond_true = N; - 3'b010: cond_true = ~V; - 3'b011: cond_true = V; - 3'b100: cond_true = ~C; - 3'b101: cond_true = C; - 3'b110: cond_true = ~Z; - 3'b111: cond_true = Z; - endcase - - -reg NMI_1 = 0; // delayed NMI signal - -always @(posedge clk) - NMI_1 <= NMI; - -always @(posedge clk ) - if( NMI_edge && state == BRK3 ) - NMI_edge <= 0; - else if( NMI & ~NMI_1 ) - NMI_edge <= 1; - -endmodule diff --git a/hw/efinix_fpga/simulation/src/verilog-6502/cpu_65c02.v b/hw/efinix_fpga/simulation/src/verilog-6502/cpu_65c02.v deleted file mode 100644 index 967b7a3..0000000 --- a/hw/efinix_fpga/simulation/src/verilog-6502/cpu_65c02.v +++ /dev/null @@ -1,1418 +0,0 @@ -/* - * verilog model of 65C02 CPU. - * - * Based on original 6502 "Arlet 6502 Core" by Arlet Ottens - * - * (C) Arlet Ottens, - * - * Feel free to use this code in any project (commercial or not), as long as you - * keep this message, and the copyright notice. This code is provided "as is", - * without any warranties of any kind. - * - * Support for 65C02 instructions and addressing modes by David Banks and Ed Spittles - * - * (C) 2016 David Banks and Ed Spittles - * - * Feel free to use this code in any project (commercial or not), as long as you - * keep this message, and the copyright notice. This code is provided "as is", - * without any warranties of any kind. - * - */ - -/* - * Note that not all 6502 interface signals are supported (yet). The goal - * is to create an Acorn Atom model, and the Atom didn't use all signals on - * the main board. - * - * The data bus is implemented as separate read/write buses. Combine them - * on the output pads if external memory is required. - */ - -/* - * Two things were needed to correctly implement 65C02 NOPs - * 1. Ensure the microcode state machine uses an appropriate addressing mode for the opcode length - * 2. Ensure there are no side-effects (e.g. register updates, memory stores, etc) - * - * If IMPLEMENT_NOPS is defined, the state machine is modified accordingly. - */ - -`define IMPLEMENT_NOPS - -/* - * Two things were needed to correctly implement 65C02 BCD arithmentic - * 1. The Z flag needs calculating over the BCD adjusted ALU output - * 2. The N flag needs calculating over the BCD adjusted ALU output - * - * If IMPLEMENT_CORRECT_BCD_FLAGS is defined, this additional logic is added - */ - -// `define IMPLEMENT_CORRECT_BCD_FLAGS - -module cpu_65c02( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY, SYNC ); - -input clk; // CPU clock -input reset; // reset signal -output reg [15:0] AB; // address bus -input [7:0] DI; // data in, read bus -output [7:0] DO; // data out, write bus -output WE; // write enable -input IRQ; // interrupt request -input NMI; // non-maskable interrupt request -input RDY; // Ready signal. Pauses CPU when RDY=0 -output reg SYNC; // AB is first cycle of the intruction - -/* - * internal signals - */ - -reg [15:0] PC; // Program Counter -reg [7:0] ABL; // Address Bus Register LSB -reg [7:0] ABH; // Address Bus Register MSB -wire [7:0] ADD; // Adder Hold Register (registered in ALU) - -reg [7:0] DIHOLD; // Hold for Data In -reg DIHOLD_valid; // -wire [7:0] DIMUX; // - -reg [7:0] IRHOLD; // Hold for Instruction register -reg IRHOLD_valid; // Valid instruction in IRHOLD - -reg [7:0] AXYS[3:0]; // A, X, Y and S register file - -reg C = 0; // carry flag (init at zero to avoid X's in ALU sim) -reg Z = 0; // zero flag -reg I = 0; // interrupt flag -reg D = 0; // decimal flag -reg V = 0; // overflow flag -reg N = 0; // negative flag -wire AZ; // ALU Zero flag -wire AZ1; // ALU Zero flag (BCD adjusted) -reg AZ2; // ALU Second Zero flag, set using TSB/TRB semantics -wire AV; // ALU overflow flag -wire AN; // ALU negative flag -wire AN1; // ALU negative flag (BCD adjusted) -wire HC; // ALU half carry - -reg [7:0] AI; // ALU Input A -reg [7:0] BI; // ALU Input B -wire [7:0] DI; // Data In -wire [7:0] IR; // Instruction register -reg [7:0] DO; // Data Out -wire [7:0] AO; // ALU output after BCD adjustment -reg WE; // Write Enable -reg CI; // Carry In -wire CO; // Carry Out -wire [7:0] PCH = PC[15:8]; -wire [7:0] PCL = PC[7:0]; - -reg NMI_edge = 0; // captured NMI edge - -reg [1:0] regsel; // Select A, X, Y or S register -wire [7:0] regfile = AXYS[regsel]; // Selected register output - -parameter - SEL_A = 2'd0, - SEL_S = 2'd1, - SEL_X = 2'd2, - SEL_Y = 2'd3; - -/* - * define some signals for watching in simulator output - */ - - -`ifdef SIM -wire [7:0] A = AXYS[SEL_A]; // Accumulator -wire [7:0] X = AXYS[SEL_X]; // X register -wire [7:0] Y = AXYS[SEL_Y]; // Y register -wire [7:0] S = AXYS[SEL_S]; // Stack pointer -`endif - -wire [7:0] P = { N, V, 2'b11, D, I, Z, C }; - -/* - * instruction decoder/sequencer - */ - -reg [5:0] state; - -/* - * control signals - */ - -reg PC_inc; // Increment PC -reg [15:0] PC_temp; // intermediate value of PC - -reg [1:0] src_reg; // source register index -reg [1:0] dst_reg; // destination register index - -reg index_y; // if set, then Y is index reg rather than X -reg load_reg; // loading a register (A, X, Y, S) in this instruction -reg inc; // increment -reg write_back; // set if memory is read/modified/written -reg load_only; // LDA/LDX/LDY instruction -reg store; // doing store (STA/STX/STY) -reg adc_sbc; // doing ADC/SBC -reg compare; // doing CMP/CPY/CPX -reg shift; // doing shift/rotate instruction -reg rotate; // doing rotate (no shift) -reg backwards; // backwards branch -reg cond_true; // branch condition is true -reg [3:0] cond_code; // condition code bits from instruction -reg shift_right; // Instruction ALU shift/rotate right -reg alu_shift_right; // Current cycle shift right enable -reg [3:0] op; // Main ALU operation for instruction -reg [3:0] alu_op; // Current cycle ALU operation -reg adc_bcd; // ALU should do BCD style carry -reg adj_bcd; // results should be BCD adjusted - -/* - * some flip flops to remember we're doing special instructions. These - * get loaded at the DECODE state, and used later - */ -reg store_zero; // doing STZ instruction -reg trb_ins; // doing TRB instruction -reg txb_ins; // doing TSB/TRB instruction -reg bit_ins; // doing BIT instruction -reg bit_ins_nv; // doing BIT instruction that will update the n and v flags (i.e. not BIT imm) -reg plp; // doing PLP instruction -reg php; // doing PHP instruction -reg clc; // clear carry -reg sec; // set carry -reg cld; // clear decimal -reg sed; // set decimal -reg cli; // clear interrupt -reg sei; // set interrupt -reg clv; // clear overflow - -reg res; // in reset - -/* - * ALU operations - */ - -parameter - OP_OR = 4'b1100, - OP_AND = 4'b1101, - OP_EOR = 4'b1110, - OP_ADD = 4'b0011, - OP_SUB = 4'b0111, - OP_ROL = 4'b1011, - OP_A = 4'b1111; - -/* - * Microcode state machine. Basically, every addressing mode has its own - * path through the state machine. Additional information, such as the - * operation, source and destination registers are decoded in parallel, and - * kept in separate flops. - */ - -parameter - ABS0 = 6'd0, // ABS - fetch LSB - ABS1 = 6'd1, // ABS - fetch MSB - ABSX0 = 6'd2, // ABS, X - fetch LSB and send to ALU (+X) - ABSX1 = 6'd3, // ABS, X - fetch MSB and send to ALU (+Carry) - ABSX2 = 6'd4, // ABS, X - Wait for ALU (only if needed) - BRA0 = 6'd5, // Branch - fetch offset and send to ALU (+PC[7:0]) - BRA1 = 6'd6, // Branch - fetch opcode, and send PC[15:8] to ALU - BRA2 = 6'd7, // Branch - fetch opcode (if page boundary crossed) - BRK0 = 6'd8, // BRK/IRQ - push PCH, send S to ALU (-1) - BRK1 = 6'd9, // BRK/IRQ - push PCL, send S to ALU (-1) - BRK2 = 6'd10, // BRK/IRQ - push P, send S to ALU (-1) - BRK3 = 6'd11, // BRK/IRQ - write S, and fetch @ fffe - DECODE = 6'd12, // IR is valid, decode instruction, and write prev reg - FETCH = 6'd13, // fetch next opcode, and perform prev ALU op - INDX0 = 6'd14, // (ZP,X) - fetch ZP address, and send to ALU (+X) - INDX1 = 6'd15, // (ZP,X) - fetch LSB at ZP+X, calculate ZP+X+1 - INDX2 = 6'd16, // (ZP,X) - fetch MSB at ZP+X+1 - INDX3 = 6'd17, // (ZP,X) - fetch data - INDY0 = 6'd18, // (ZP),Y - fetch ZP address, and send ZP to ALU (+1) - INDY1 = 6'd19, // (ZP),Y - fetch at ZP+1, and send LSB to ALU (+Y) - INDY2 = 6'd20, // (ZP),Y - fetch data, and send MSB to ALU (+Carry) - INDY3 = 6'd21, // (ZP),Y) - fetch data (if page boundary crossed) - JMP0 = 6'd22, // JMP - fetch PCL and hold - JMP1 = 6'd23, // JMP - fetch PCH - JMPI0 = 6'd24, // JMP IND - fetch LSB and send to ALU for delay (+0) - JMPI1 = 6'd25, // JMP IND - fetch MSB, proceed with JMP0 state - JSR0 = 6'd26, // JSR - push PCH, save LSB, send S to ALU (-1) - JSR1 = 6'd27, // JSR - push PCL, send S to ALU (-1) - JSR2 = 6'd28, // JSR - write S - JSR3 = 6'd29, // JSR - fetch MSB - PULL0 = 6'd30, // PLP/PLA/PLX/PLY - save next op in IRHOLD, send S to ALU (+1) - PULL1 = 6'd31, // PLP/PLA/PLX/PLY - fetch data from stack, write S - PULL2 = 6'd32, // PLP/PLA/PLX/PLY - prefetch op, but don't increment PC - PUSH0 = 6'd33, // PHP/PHA/PHX/PHY - send A to ALU (+0) - PUSH1 = 6'd34, // PHP/PHA/PHX/PHY - write A/P, send S to ALU (-1) - READ = 6'd35, // Read memory for read/modify/write (INC, DEC, shift) - REG = 6'd36, // Read register for reg-reg transfers - RTI0 = 6'd37, // RTI - send S to ALU (+1) - RTI1 = 6'd38, // RTI - read P from stack - RTI2 = 6'd39, // RTI - read PCL from stack - RTI3 = 6'd40, // RTI - read PCH from stack - RTI4 = 6'd41, // RTI - read PCH from stack - RTS0 = 6'd42, // RTS - send S to ALU (+1) - RTS1 = 6'd43, // RTS - read PCL from stack - RTS2 = 6'd44, // RTS - write PCL to ALU, read PCH - RTS3 = 6'd45, // RTS - load PC and increment - WRITE = 6'd46, // Write memory for read/modify/write - ZP0 = 6'd47, // Z-page - fetch ZP address - ZPX0 = 6'd48, // ZP, X - fetch ZP, and send to ALU (+X) - ZPX1 = 6'd49, // ZP, X - load from memory - IND0 = 6'd50, // (ZP) - fetch ZP address, and send to ALU (+0) - JMPIX0 = 6'd51, // JMP (,X)- fetch LSB and send to ALU (+X) - JMPIX1 = 6'd52, // JMP (,X)- fetch MSB and send to ALU (+Carry) - JMPIX2 = 6'd53; // JMP (,X)- Wait for ALU (only if needed) - -`ifdef SIM - -/* - * easy to read names in simulator output - */ -reg [8*6-1:0] statename; - -always @* - case( state ) - DECODE: statename = "DECODE"; - REG: statename = "REG"; - ZP0: statename = "ZP0"; - ZPX0: statename = "ZPX0"; - ZPX1: statename = "ZPX1"; - ABS0: statename = "ABS0"; - ABS1: statename = "ABS1"; - ABSX0: statename = "ABSX0"; - ABSX1: statename = "ABSX1"; - ABSX2: statename = "ABSX2"; - IND0: statename = "IND0"; - INDX0: statename = "INDX0"; - INDX1: statename = "INDX1"; - INDX2: statename = "INDX2"; - INDX3: statename = "INDX3"; - INDY0: statename = "INDY0"; - INDY1: statename = "INDY1"; - INDY2: statename = "INDY2"; - INDY3: statename = "INDY3"; - READ: statename = "READ"; - WRITE: statename = "WRITE"; - FETCH: statename = "FETCH"; - PUSH0: statename = "PUSH0"; - PUSH1: statename = "PUSH1"; - PULL0: statename = "PULL0"; - PULL1: statename = "PULL1"; - PULL2: statename = "PULL2"; - JSR0: statename = "JSR0"; - JSR1: statename = "JSR1"; - JSR2: statename = "JSR2"; - JSR3: statename = "JSR3"; - RTI0: statename = "RTI0"; - RTI1: statename = "RTI1"; - RTI2: statename = "RTI2"; - RTI3: statename = "RTI3"; - RTI4: statename = "RTI4"; - RTS0: statename = "RTS0"; - RTS1: statename = "RTS1"; - RTS2: statename = "RTS2"; - RTS3: statename = "RTS3"; - BRK0: statename = "BRK0"; - BRK1: statename = "BRK1"; - BRK2: statename = "BRK2"; - BRK3: statename = "BRK3"; - BRA0: statename = "BRA0"; - BRA1: statename = "BRA1"; - BRA2: statename = "BRA2"; - JMP0: statename = "JMP0"; - JMP1: statename = "JMP1"; - JMPI0: statename = "JMPI0"; - JMPI1: statename = "JMPI1"; - JMPIX0: statename = "JMPIX0"; - JMPIX1: statename = "JMPIX1"; - JMPIX2: statename = "JMPIX2"; - - endcase - -//always @( PC ) -// $display( "%t, PC:%04x IR:%02x A:%02x X:%02x Y:%02x S:%02x C:%d Z:%d V:%d N:%d P:%02x", $time, PC, IR, A, X, Y, S, C, Z, V, N, P ); - -`endif - - - -/* - * Program Counter Increment/Load. First calculate the base value in - * PC_temp. - */ -always @* - case( state ) - DECODE: if( (~I & IRQ) | NMI_edge ) - PC_temp = { ABH, ABL }; - else - PC_temp = PC; - - - JMP1, - JMPI1, - JMPIX1, - JSR3, - RTS3, - RTI4: PC_temp = { DIMUX, ADD }; - - BRA1: PC_temp = { ABH, ADD }; - - JMPIX2, - BRA2: PC_temp = { ADD, PCL }; - - BRK2: PC_temp = res ? 16'hfffc : - NMI_edge ? 16'hfffa : 16'hfffe; - - default: PC_temp = PC; - endcase - -/* - * Determine wether we need PC_temp, or PC_temp + 1 - */ -always @* - case( state ) - DECODE: if( (~I & IRQ) | NMI_edge ) - PC_inc = 0; - else - PC_inc = 1; - - ABS0, - JMPIX0, - JMPIX2, - ABSX0, - FETCH, - BRA0, - BRA2, - BRK3, - JMPI1, - JMP1, - RTI4, - RTS3: PC_inc = 1; - - JMPIX1: PC_inc = ~CO; // Don't increment PC if we are going to go through JMPIX2 - - BRA1: PC_inc = CO ^~ backwards; - - default: PC_inc = 0; - endcase - -/* - * Set new PC - */ -always @(posedge clk) - if( RDY ) - PC <= PC_temp + PC_inc; - -/* - * Address Generator - */ - -parameter - ZEROPAGE = 8'h00, - STACKPAGE = 8'h01; - -always @* - case( state ) - JMPIX1, - ABSX1, - INDX3, - INDY2, - JMP1, - JMPI1, - RTI4, - ABS1: AB = { DIMUX, ADD }; - - BRA2, - INDY3, - JMPIX2, - ABSX2: AB = { ADD, ABL }; - - BRA1: AB = { ABH, ADD }; - - JSR0, - PUSH1, - RTS0, - RTI0, - BRK0: AB = { STACKPAGE, regfile }; - - BRK1, - JSR1, - PULL1, - RTS1, - RTS2, - RTI1, - RTI2, - RTI3, - BRK2: AB = { STACKPAGE, ADD }; - - INDY1, - INDX1, - ZPX1, - INDX2: AB = { ZEROPAGE, ADD }; - - ZP0, - INDY0: AB = { ZEROPAGE, DIMUX }; - - REG, - READ, - WRITE: AB = { ABH, ABL }; - - default: AB = PC; - endcase - -/* - * ABH/ABL pair is used for registering previous address bus state. - * This can be used to keep the current address, freeing up the original - * source of the address, such as the ALU or DI. - */ -always @(posedge clk) - if( state != PUSH0 && state != PUSH1 && RDY && - state != PULL0 && state != PULL1 && state != PULL2 ) - begin - ABL <= AB[7:0]; - ABH <= AB[15:8]; - end - -/* - * Data Out MUX - */ -always @* - case( state ) - WRITE: DO = ADD; - - JSR0, - BRK0: DO = PCH; - - JSR1, - BRK1: DO = PCL; - - PUSH1: DO = php ? P : ADD; - - BRK2: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P; - - default: DO = store_zero ? 8'b0 : regfile; - endcase - -/* - * Write Enable Generator - */ - -always @* - case( state ) - BRK0, // writing to stack or memory - BRK1, - BRK2, - JSR0, - JSR1, - PUSH1, - WRITE: WE = 1; - - INDX3, // only if doing a STA, STX or STY - INDY3, - ABSX2, - ABS1, - ZPX1, - ZP0: WE = store; - - default: WE = 0; - endcase - -/* - * register file, contains A, X, Y and S (stack pointer) registers. At each - * cycle only 1 of those registers needs to be accessed, so they combined - * in a small memory, saving resources. - */ - -reg write_register; // set when register file is written - -always @* - case( state ) - DECODE: write_register = load_reg & ~plp; - - PULL1, - RTS2, - RTI3, - BRK3, - JSR0, - JSR2 : write_register = 1; - - default: write_register = 0; - endcase - -/* - * BCD adjust logic - */ - -always @(posedge clk) - adj_bcd <= adc_sbc & D; // '1' when doing a BCD instruction - -reg [3:0] ADJL; -reg [3:0] ADJH; - -// adjustment term to be added to ADD[3:0] based on the following -// adj_bcd: '1' if doing ADC/SBC with D=1 -// adc_bcd: '1' if doing ADC with D=1 -// HC : half carry bit from ALU -always @* begin - casex( {adj_bcd, adc_bcd, HC} ) - 3'b0xx: ADJL = 4'd0; // no BCD instruction - 3'b100: ADJL = 4'd10; // SBC, and digital borrow - 3'b101: ADJL = 4'd0; // SBC, but no borrow - 3'b110: ADJL = 4'd0; // ADC, but no carry - 3'b111: ADJL = 4'd6; // ADC, and decimal/digital carry - endcase -end - -// adjustment term to be added to ADD[7:4] based on the following -// adj_bcd: '1' if doing ADC/SBC with D=1 -// adc_bcd: '1' if doing ADC with D=1 -// CO : carry out bit from ALU -always @* begin - casex( {adj_bcd, adc_bcd, CO} ) - 3'b0xx: ADJH = 4'd0; // no BCD instruction - 3'b100: ADJH = 4'd10; // SBC, and digital borrow - 3'b101: ADJH = 4'd0; // SBC, but no borrow - 3'b110: ADJH = 4'd0; // ADC, but no carry - 3'b111: ADJH = 4'd6; // ADC, and decimal/digital carry - endcase -end - -assign AO = { ADD[7:4] + ADJH, ADD[3:0] + ADJL }; - -`ifdef IMPLEMENT_CORRECT_BCD_FLAGS - -assign AN1 = AO[7]; -assign AZ1 = ~|AO; - -`else - -assign AN1 = AN; -assign AZ1 = AZ; - -`endif - -/* - * write to a register. Usually this is the (BCD corrected) output of the - * ALU, but in case of the JSR0 we use the S register to temporarily store - * the PCL. This is possible, because the S register itself is stored in - * the ALU during those cycles. - */ -always @(posedge clk) - if( write_register & RDY ) - AXYS[regsel] <= (state == JSR0) ? DIMUX : AO; - -/* - * register select logic. This determines which of the A, X, Y or - * S registers will be accessed. - */ - -always @* - case( state ) - INDY1, - INDX0, - ZPX0, - JMPIX0, - ABSX0 : regsel = index_y ? SEL_Y : SEL_X; - - - DECODE : regsel = dst_reg; - - BRK0, - BRK3, - JSR0, - JSR2, - PULL0, - PULL1, - PUSH1, - RTI0, - RTI3, - RTS0, - RTS2 : regsel = SEL_S; - - default: regsel = src_reg; - endcase - -/* - * ALU - */ - -ALU ALU( .clk(clk), - .op(alu_op), - .right(alu_shift_right), - .AI(AI), - .BI(BI), - .CI(CI), - .BCD(adc_bcd & (state == FETCH)), - .CO(CO), - .OUT(ADD), - .V(AV), - .Z(AZ), - .N(AN), - .HC(HC), - .RDY(RDY) ); - -/* - * Select current ALU operation - */ - -always @* - case( state ) - READ: alu_op = op; - - BRA1: alu_op = backwards ? OP_SUB : OP_ADD; - - FETCH, - REG : alu_op = op; - - DECODE, - ABS1: alu_op = 1'bx; - - PUSH1, - BRK0, - BRK1, - BRK2, - JSR0, - JSR1: alu_op = OP_SUB; - - default: alu_op = OP_ADD; - endcase - -/* - * Determine shift right signal to ALU - */ - -always @* - if( state == FETCH || state == REG || state == READ ) - alu_shift_right = shift_right; - else - alu_shift_right = 0; - -/* - * Sign extend branch offset. - */ - -always @(posedge clk) - if( RDY ) - backwards <= DIMUX[7]; - -/* - * ALU A Input MUX - */ - -always @* - case( state ) - JSR1, - RTS1, - RTI1, - RTI2, - BRK1, - BRK2, - INDX1: AI = ADD; - - REG, - ZPX0, - INDX0, - JMPIX0, - ABSX0, - RTI0, - RTS0, - JSR0, - JSR2, - BRK0, - PULL0, - INDY1, - PUSH0, - PUSH1: AI = regfile; - - BRA0, - READ: AI = DIMUX; - - BRA1: AI = ABH; // don't use PCH in case we're - - FETCH: AI = load_only ? 8'b0 : regfile; - - DECODE, - ABS1: AI = 8'hxx; // don't care - - default: AI = 0; - endcase - - -/* - * ALU B Input mux - */ - -always @* - case( state ) - BRA1, - RTS1, - RTI0, - RTI1, - RTI2, - INDX1, - REG, - JSR0, - JSR1, - JSR2, - BRK0, - BRK1, - BRK2, - PUSH0, - PUSH1, - PULL0, - RTS0: BI = 8'h00; - - READ: BI = txb_ins ? (trb_ins ? ~regfile : regfile) : 8'h00; - - BRA0: BI = PCL; - - DECODE, - ABS1: BI = 8'hxx; - - default: BI = DIMUX; - endcase - -/* - * ALU CI (carry in) mux - */ - -always @* - case( state ) - INDY2, - BRA1, - JMPIX1, - ABSX1: CI = CO; - - DECODE, - ABS1: CI = 1'bx; - - READ, - REG: CI = rotate ? C : - shift ? 1'b0 : inc; - - FETCH: CI = rotate ? C : - compare ? 1'b1 : - (shift | load_only) ? 1'b0 : C; - - PULL0, - RTI0, - RTI1, - RTI2, - RTS0, - RTS1, - INDY0, - INDX1: CI = 1; - - default: CI = 0; - endcase - -/* - * Processor Status Register update - * - */ - -/* - * Update C flag when doing ADC/SBC, shift/rotate, compare - */ -always @(posedge clk ) - if( shift && state == WRITE ) - C <= CO; - else if( state == RTI2 ) - C <= DIMUX[0]; - else if( ~write_back && state == DECODE ) begin - if( adc_sbc | shift | compare ) - C <= CO; - else if( plp ) - C <= ADD[0]; - else begin - if( sec ) C <= 1; - if( clc ) C <= 0; - end - end - -/* - * Special Z flag got TRB/TSB - */ -always @(posedge clk) - if (RDY) - AZ2 <= ~|(AI & regfile); - -/* - * Update Z, N flags when writing A, X, Y, Memory, or when doing compare - */ - -always @(posedge clk) - if( state == WRITE) - Z <= txb_ins ? AZ2 : AZ1; - else if( state == RTI2 ) - Z <= DIMUX[1]; - else if( state == DECODE ) begin - if( plp ) - Z <= ADD[1]; - else if( (load_reg & (regsel != SEL_S)) | compare | bit_ins ) - Z <= AZ1; - end - -always @(posedge clk) - if( state == WRITE && ~txb_ins) - N <= AN1; - else if( state == RTI2 ) - N <= DIMUX[7]; - else if( state == DECODE ) begin - if( plp ) - N <= ADD[7]; - else if( (load_reg & (regsel != SEL_S)) | compare ) - N <= AN1; - end else if( state == FETCH && bit_ins_nv ) - N <= DIMUX[7]; - -/* - * Update I flag - */ - -always @(posedge clk) - if( state == BRK3 ) - I <= 1; - else if( state == RTI2 ) - I <= DIMUX[2]; - else if( state == REG ) begin - if( sei ) I <= 1; - if( cli ) I <= 0; - end else if( state == DECODE ) - if( plp ) I <= ADD[2]; - -/* - * Update D flag - */ -always @(posedge clk ) - if( state == RTI2 ) - D <= DIMUX[3]; - else if( state == DECODE ) begin - if( sed ) D <= 1; - if( cld ) D <= 0; - if( plp ) D <= ADD[3]; - end - -/* - * Update V flag - */ -always @(posedge clk ) - if( state == RTI2 ) - V <= DIMUX[6]; - else if( state == DECODE ) begin - if( adc_sbc ) V <= AV; - if( clv ) V <= 0; - if( plp ) V <= ADD[6]; - end else if( state == FETCH && bit_ins_nv ) - V <= DIMUX[6]; - -/* - * Instruction decoder - */ - -/* - * IR register/mux. Hold previous DI value in IRHOLD in PULL0 and PUSH0 - * states. In these states, the IR has been prefetched, and there is no - * time to read the IR again before the next decode. - */ - -//reg RDY1 = 1; - -//always @(posedge clk ) -// RDY1 <= RDY; - -//always @(posedge clk ) -// if( ~RDY && RDY1 ) -// DIHOLD <= DI; - -always @(posedge clk ) - if( reset ) - IRHOLD_valid <= 0; - else if( RDY ) begin - if( state == PULL0 || state == PUSH0 ) begin - IRHOLD <= DIMUX; - IRHOLD_valid <= 1; - end else if( state == DECODE ) - IRHOLD_valid <= 0; - end - -assign IR = (IRQ & ~I) | NMI_edge ? 8'h00 : - IRHOLD_valid ? IRHOLD : DIMUX; - -//assign DIMUX = ~RDY1 ? DIHOLD : DI; - -assign DIMUX = DI; - -/* - * Microcode state machine - */ -always @(posedge clk or posedge reset) - if( reset ) - state <= BRK0; - else if( RDY ) case( state ) - DECODE : - casex ( IR ) - // TODO Review for simplifications as in verilog the first matching case has priority - 8'b0000_0000: state <= BRK0; - 8'b0010_0000: state <= JSR0; - 8'b0010_1100: state <= ABS0; // BIT abs - 8'b1001_1100: state <= ABS0; // STZ abs - 8'b000x_1100: state <= ABS0; // TSB/TRB - 8'b0100_0000: state <= RTI0; // - 8'b0100_1100: state <= JMP0; - 8'b0110_0000: state <= RTS0; - 8'b0110_1100: state <= JMPI0; - 8'b0111_1100: state <= JMPIX0; -`ifdef IMPLEMENT_NOPS - 8'bxxxx_xx11: state <= REG; // (NOP1: 3/7/B/F column) - 8'bxxx0_0010: state <= FETCH; // (NOP2: 2 column, 4 column handled correctly below) - 8'bx1x1_1100: state <= ABS0; // (NOP3: C column) -`endif - 8'b0x00_1000: state <= PUSH0; - 8'b0x10_1000: state <= PULL0; - 8'b0xx1_1000: state <= REG; // CLC, SEC, CLI, SEI - 8'b11x0_00x0: state <= FETCH; // IMM - 8'b1x10_00x0: state <= FETCH; // IMM - 8'b1xx0_1100: state <= ABS0; // X/Y abs - 8'b1xxx_1000: state <= REG; // DEY, TYA, ... - 8'bxxx0_0001: state <= INDX0; - 8'bxxx1_0010: state <= IND0; // (ZP) odd 2 column - 8'b000x_0100: state <= ZP0; // TSB/TRB - 8'bxxx0_01xx: state <= ZP0; - 8'bxxx0_1001: state <= FETCH; // IMM - 8'bxxx0_1101: state <= ABS0; // even D column - 8'bxxx0_1110: state <= ABS0; // even E column - 8'bxxx1_0000: state <= BRA0; // odd 0 column (Branches) - 8'b1000_0000: state <= BRA0; // BRA - 8'bxxx1_0001: state <= INDY0; // odd 1 column - 8'bxxx1_01xx: state <= ZPX0; // odd 4,5,6,7 columns - 8'bxxx1_1001: state <= ABSX0; // odd 9 column - 8'bx011_1100: state <= ABSX0; // C column BIT (3C), LDY (BC) - 8'bxxx1_11x1: state <= ABSX0; // odd D, F columns - 8'bxxx1_111x: state <= ABSX0; // odd E, F columns - 8'bx101_1010: state <= PUSH0; // PHX/PHY - 8'bx111_1010: state <= PULL0; // PLX/PLY - 8'bx0xx_1010: state <= REG; // A, TXA, ... NOP - 8'bxxx0_1010: state <= REG; // A, TXA, ... NOP - endcase - - ZP0 : state <= write_back ? READ : FETCH; - - ZPX0 : state <= ZPX1; - ZPX1 : state <= write_back ? READ : FETCH; - - ABS0 : state <= ABS1; - ABS1 : state <= write_back ? READ : FETCH; - - ABSX0 : state <= ABSX1; - ABSX1 : state <= (CO | store | write_back) ? ABSX2 : FETCH; - ABSX2 : state <= write_back ? READ : FETCH; - - JMPIX0 : state <= JMPIX1; - JMPIX1 : state <= CO ? JMPIX2 : JMP0; - JMPIX2 : state <= JMP0; - - IND0 : state <= INDX1; - - INDX0 : state <= INDX1; - INDX1 : state <= INDX2; - INDX2 : state <= INDX3; - INDX3 : state <= FETCH; - - INDY0 : state <= INDY1; - INDY1 : state <= INDY2; - INDY2 : state <= (CO | store) ? INDY3 : FETCH; - INDY3 : state <= FETCH; - - READ : state <= WRITE; - WRITE : state <= FETCH; - FETCH : state <= DECODE; - - REG : state <= DECODE; - - PUSH0 : state <= PUSH1; - PUSH1 : state <= DECODE; - - PULL0 : state <= PULL1; - PULL1 : state <= PULL2; - PULL2 : state <= DECODE; - - JSR0 : state <= JSR1; - JSR1 : state <= JSR2; - JSR2 : state <= JSR3; - JSR3 : state <= FETCH; - - RTI0 : state <= RTI1; - RTI1 : state <= RTI2; - RTI2 : state <= RTI3; - RTI3 : state <= RTI4; - RTI4 : state <= DECODE; - - RTS0 : state <= RTS1; - RTS1 : state <= RTS2; - RTS2 : state <= RTS3; - RTS3 : state <= FETCH; - - BRA0 : state <= cond_true ? BRA1 : DECODE; - BRA1 : state <= (CO ^ backwards) ? BRA2 : DECODE; - BRA2 : state <= DECODE; - - JMP0 : state <= JMP1; - JMP1 : state <= DECODE; - - JMPI0 : state <= JMPI1; - JMPI1 : state <= JMP0; - - BRK0 : state <= BRK1; - BRK1 : state <= BRK2; - BRK2 : state <= BRK3; - BRK3 : state <= JMP0; - - endcase - - -/* - * Sync state machine - */ -always @(posedge clk or posedge reset) - if( reset ) - SYNC <= 1'b0; - else if( RDY ) case( state ) - BRA0 : SYNC <= !cond_true; - BRA1 : SYNC <= !(CO ^ backwards); - BRA2, - FETCH, - REG, - PUSH1, - PULL2, - RTI4, - JMP1, - BRA2 : SYNC <= 1'b1; - default: SYNC <= 1'b0; - endcase - -//assign SYNC = state == DECODE; - -/* - * Additional control signals - */ - -always @(posedge clk) - if( reset ) - res <= 1; - else if( state == DECODE ) - res <= 0; - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) // DMB: Checked for 65C02 NOP collisions - 8'b0xx1_0010, // ORA, AND, EOR, ADC (zp) - 8'b1x11_0010, // LDA, SBC (zp) - 8'b0xxx_1010, // ASLA, INCA, ROLA, DECA, LSRA, PHY, RORA, PLY - 8'b0xxx_xx01, // ORA, AND, EOR, ADC - 8'b100x_10x0, // DEY, TYA, TXA, TXS - 8'b1010_xxx0, // LDA/LDX/LDY - 8'b1011_1010, // TSX - 8'b1011_x1x0, // LDX/LDY - 8'b1100_1010, // DEX - 8'b11x1_1010, // PHX, PLX - 8'b1x1x_xx01, // LDA, SBC - 8'bxxx0_1000: // PHP, PLP, PHA, PLA, DEY, TAY, INY, INX - load_reg <= 1; - - default: load_reg <= 0; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1110_1000, // INX - 8'b1100_1010, // DEX - 8'b1111_1010, // PLX - 8'b1010_0010, // LDX imm - 8'b101x_x110, // LDX - 8'b101x_1x10: // LDX, TAX, TSX - dst_reg <= SEL_X; - - 8'b0x00_1000, // PHP, PHA - 8'bx101_1010, // PHX, PHY - 8'b1001_1010: // TXS - dst_reg <= SEL_S; - - 8'b1x00_1000, // DEY, DEX - 8'b0111_1010, // PLY - 8'b101x_x100, // LDY - 8'b1010_x000: // LDY #imm, TAY - dst_reg <= SEL_Y; - - default: dst_reg <= SEL_A; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1011_1010: // TSX - src_reg <= SEL_S; - - 8'b100x_x110, // STX - 8'b100x_1x10, // TXA, TXS - 8'b1110_xx00, // INX, CPX - 8'b1101_1010, // PHX - 8'b1100_1010: // DEX - src_reg <= SEL_X; - - 8'b100x_x100, // STY - 8'b1001_1000, // TYA - 8'b1100_xx00, // CPY - 8'b0101_1010, // PHY - 8'b1x00_1000: // DEY, INY - src_reg <= SEL_Y; - - default: src_reg <= SEL_A; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'bxxx1_0001, // INDY - 8'b10x1_0110, // LDX zp,Y / STX zp,Y - 8'b1011_1110, // LDX abs,Y - 8'bxxxx_1001: // abs, Y - index_y <= 1; - - default: index_y <= 0; - endcase - - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) // DMB: Checked for 65C02 NOP collisions - 8'b1001_0010, // STA (zp) - 8'b100x_x1x0, // STX, STY, STZ abs, STZ abs,x - 8'b011x_0100, // STZ zp, STZ zp,x - 8'b100x_xx01: // STA - store <= 1; - - default: store <= 0; - - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) // DMB: Checked for 65C02 NOP collisions - 8'b0xxx_x110, // ASL, ROL, LSR, ROR - 8'b000x_x100, // TSB/TRB - 8'b11xx_x110: // DEC/INC - write_back <= 1; - - default: write_back <= 0; - endcase - - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b101x_xxxx: // LDA, LDX, LDY - load_only <= 1; - default: load_only <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0001_1010, // INCA - 8'b111x_x110, // INC - 8'b11x0_1000: // INX, INY - inc <= 1; - - default: inc <= 0; - endcase - -always @(posedge clk ) - if( (state == DECODE || state == BRK0) && RDY ) - casex( IR ) - 8'bx111_0010, // SBC (zp), ADC (zp) - 8'bx11x_xx01: // SBC, ADC - adc_sbc <= 1; - - default: adc_sbc <= 0; - endcase - -always @(posedge clk ) - if( (state == DECODE || state == BRK0) && RDY ) - casex( IR ) - 8'b0111_0010, // ADC (zp) - 8'b011x_xx01: // ADC - adc_bcd <= D; - - default: adc_bcd <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0xxx_x110, // ASL, ROL, LSR, ROR (abs, absx, zpg, zpgx) - 8'b0xx0_1010: // ASL, ROL, LSR, ROR (acc) - shift <= 1; - - default: shift <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1101_0010, // CMP (zp) - 8'b11x0_0x00, // CPX, CPY (imm/zp) - 8'b11x0_1100, // CPX, CPY (abs) - 8'b110x_xx01: // CMP - compare <= 1; - - default: compare <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b01xx_x110, // ROR, LSR - 8'b01xx_1x10: // ROR, LSR - shift_right <= 1; - - default: shift_right <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0x10_1010, // ROL A, ROR A - 8'b0x1x_x110: // ROR, ROL - rotate <= 1; - - default: rotate <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0000_x100: // TSB - op <= OP_OR; - - 8'b0001_x100: // TRB - op <= OP_AND; - - 8'b00xx_x110, // ROL, ASL - 8'b00x0_1010: // ROL, ASL - op <= OP_ROL; - - 8'b1000_1001, // BIT imm - 8'b001x_x100: // BIT zp/abs/zpx/absx - op <= OP_AND; - - 8'b01xx_x110, // ROR, LSR - 8'b01xx_1x10: // ROR, LSR - op <= OP_A; - - 8'b11x1_0010, // CMP, SBC (zp) - 8'b0011_1010, // DEC A - 8'b1000_1000, // DEY - 8'b1100_1010, // DEX - 8'b110x_x110, // DEC - 8'b11xx_xx01, // CMP, SBC - 8'b11x0_0x00, // CPX, CPY (imm, zpg) - 8'b11x0_1100: op <= OP_SUB; - - 8'b00x1_0010, // ORA, AND (zp) - 8'b0x01_0010, // ORA, EOR (zp) - 8'b010x_xx01, // EOR - 8'b00xx_xx01: // ORA, AND - op <= { 2'b11, IR[6:5] }; - - default: op <= OP_ADD; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b001x_x100: // BIT zp/abs/zpx/absx (update N,V,Z) - {bit_ins, bit_ins_nv} <= 2'b11; - - 8'b1000_1001: // BIT imm (update Z) - {bit_ins, bit_ins_nv} <= 2'b10; - - default: // not a BIT instruction - {bit_ins, bit_ins_nv} <= 2'b00; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b000x_x100: // TRB/TSB - txb_ins <= 1; - - default: txb_ins <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0001_x100: // TRB - trb_ins <= 1; - - default: trb_ins <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1001_11x0, // STZ abs, STZ abs,x - 8'b011x_0100: // STZ zp, STZ zp,x - store_zero <= 1; - - default: store_zero <= 0; - endcase - -/* - * special instructions - */ -always @(posedge clk ) - if( state == DECODE && RDY ) begin - php <= (IR == 8'h08); - clc <= (IR == 8'h18); - plp <= (IR == 8'h28); - sec <= (IR == 8'h38); - cli <= (IR == 8'h58); - sei <= (IR == 8'h78); - clv <= (IR == 8'hb8); - cld <= (IR == 8'hd8); - sed <= (IR == 8'hf8); - end - -always @(posedge clk) - if( RDY ) - cond_code <= IR[7:4]; - -always @* - case( cond_code ) - 4'b0001: cond_true = ~N; - 4'b0011: cond_true = N; - 4'b0101: cond_true = ~V; - 4'b0111: cond_true = V; - 4'b1001: cond_true = ~C; - 4'b1011: cond_true = C; - 4'b1101: cond_true = ~Z; - 4'b1111: cond_true = Z; - default: cond_true = 1; // BRA is 80 - endcase - - -reg NMI_1 = 0; // delayed NMI signal - -always @(posedge clk) - NMI_1 <= NMI; - -always @(posedge clk ) - if( NMI_edge && state == BRK3 ) - NMI_edge <= 0; - else if( NMI & ~NMI_1 ) - NMI_edge <= 1; - -endmodule From 00173f4e890ced956711ccc7991a2a3df55a0d7f Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sat, 23 Sep 2023 09:59:39 -0700 Subject: [PATCH 07/57] Add submodule back --- .gitmodules | 5 ++++- hw/efinix_fpga/simulation/src/verilog-6502 | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) create mode 160000 hw/efinix_fpga/simulation/src/verilog-6502 diff --git a/.gitmodules b/.gitmodules index 591c898..0a0a7e3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "sw/cc65"] path = sw/cc65 - url = https://git.byronlathi.com/bslathi19/cc65 \ No newline at end of file + 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 diff --git a/hw/efinix_fpga/simulation/src/verilog-6502 b/hw/efinix_fpga/simulation/src/verilog-6502 new file mode 160000 index 0000000..a5f605d --- /dev/null +++ b/hw/efinix_fpga/simulation/src/verilog-6502 @@ -0,0 +1 @@ +Subproject commit a5f605d00d22095532cc32aa7a481465b1bdca17 From d3aa195adf417900f3e6232459e88f16717f8046 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sat, 23 Sep 2023 10:49:44 -0700 Subject: [PATCH 08/57] Add updated sim cpu with fix --- hw/efinix_fpga/simulation/Makefile | 3 ++- hw/efinix_fpga/simulation/src/sim_top.sv | 11 ++++++----- hw/efinix_fpga/simulation/src/verilog-6502 | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index 0385b34..4927c98 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -9,9 +9,10 @@ INC=$(shell find include/ -type f) TOP_MODULE=sim_top TARGET=sim_top INIT_MEM=init_hex.mem +FLAGS=-DSIM all: $(INIT_MEM) - iverilog -g2005-sv -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS) + iverilog -g2005-sv $(FLAGS) -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS) $(INIT_MEM): cp ../$(INIT_MEM) . diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 703ba35..1e6664c 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -55,17 +55,17 @@ logic w_cpu_reset; logic [15:0] w_cpu_addr; logic [7:0] w_cpu_data_from_cpu, w_cpu_data_from_dut; logic cpu_rwb; +logic w_cpu_phi2; //TODO: this cpu_65c02 u_cpu( - .clk(r_clk_2), - // .reset(~w_cpu_reset), - .reset(~button_reset), + .phi2(w_cpu_phi2), + .reset(~w_cpu_reset), .AB(w_cpu_addr), .RDY('1), .IRQ('0), .NMI('0), - .DI(w_cpu_data_from_dut), + .DI_s1(w_cpu_data_from_dut), // .DO(w_cpu_data_from_cpu), .WE(cpu_rwb) ); @@ -92,7 +92,8 @@ super6502 u_dut( .cpu_addr(w_cpu_addr), .cpu_data_out(w_cpu_data_from_dut), // .cpu_data_in(w_cpu_data_from_cpu), - .cpu_rwb(~cpu_rwb) + .cpu_rwb(~cpu_rwb), + .cpu_phi2(w_cpu_phi2) ); diff --git a/hw/efinix_fpga/simulation/src/verilog-6502 b/hw/efinix_fpga/simulation/src/verilog-6502 index a5f605d..001840c 160000 --- a/hw/efinix_fpga/simulation/src/verilog-6502 +++ b/hw/efinix_fpga/simulation/src/verilog-6502 @@ -1 +1 @@ -Subproject commit a5f605d00d22095532cc32aa7a481465b1bdca17 +Subproject commit 001840c64e5bb175672db899009fdea7a815003b From 13ea5ca71b0debf1372ca4567c3d0268bb1d3b1a Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 24 Sep 2023 10:06:23 -0700 Subject: [PATCH 09/57] Add memory --- .../super6502_sdram_controller_define.vh | 83 ++++++++++++++++--- hw/efinix_fpga/simulation/src/sim_top.sv | 66 +++++++++++++-- 2 files changed, 129 insertions(+), 20 deletions(-) diff --git a/hw/efinix_fpga/simulation/include/super6502_sdram_controller_define.vh b/hw/efinix_fpga/simulation/include/super6502_sdram_controller_define.vh index 077f158..3bbfa9a 100644 --- a/hw/efinix_fpga/simulation/include/super6502_sdram_controller_define.vh +++ b/hw/efinix_fpga/simulation/include/super6502_sdram_controller_define.vh @@ -1,23 +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 fCK_MHz = 200; localparam tIORT_u = 2; +localparam CL = 3; localparam BL = 1; localparam DDIO_TYPE = "SOFT"; -localparam DQ_WIDTH = 8; +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 tRC = 66; +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 tREF = 64000000; +localparam tRFC = 66; +localparam tRP = 20; localparam tWR = 2; localparam tMRD = 2; -localparam tRFC = 66; -localparam tRAS_MAX = 120000; +localparam SDRAM_MODE = "Native"; localparam DATA_RATE = 2; -localparam tRP = 20; -localparam CL = 3; +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; diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 1e6664c..41bd4f0 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -2,11 +2,13 @@ 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 <= '0; + r_sysclk <= '1; forever begin #5 r_sysclk <= ~r_sysclk; end @@ -54,7 +56,7 @@ 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 cpu_rwb; +logic w_cpu_we; logic w_cpu_phi2; //TODO: this @@ -66,8 +68,8 @@ cpu_65c02 u_cpu( .IRQ('0), .NMI('0), .DI_s1(w_cpu_data_from_dut), - // .DO(w_cpu_data_from_cpu), - .WE(cpu_rwb) + .DO(w_cpu_data_from_cpu), + .WE(w_cpu_we) ); @@ -91,10 +93,60 @@ super6502 u_dut( .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(~cpu_rwb), - .cpu_phi2(w_cpu_phi2) + .cpu_data_in(w_cpu_data_from_cpu), + .cpu_rwb(~w_cpu_we), + .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 Date: Sun, 24 Sep 2023 10:29:32 -0700 Subject: [PATCH 10/57] Add support for test programs --- hw/efinix_fpga/simulation/Makefile | 4 ++- sw/test_code/simple_mem_test/Makefile | 39 ++++++++++++++++++++++++++ sw/test_code/simple_mem_test/link.ld | 35 +++++++++++++++++++++++ sw/test_code/simple_mem_test/main.s | 24 ++++++++++++++++ sw/test_code/simple_mem_test/vectors.s | 14 +++++++++ 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 sw/test_code/simple_mem_test/Makefile create mode 100644 sw/test_code/simple_mem_test/link.ld create mode 100644 sw/test_code/simple_mem_test/main.s create mode 100644 sw/test_code/simple_mem_test/vectors.s diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index 4927c98..520865f 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -4,6 +4,8 @@ SRCS+=$(shell find ../src/ -type f -name "*.*v") INC=$(shell find include/ -type f) +TEST_PROGRAM=../../../sw/test_code/simple_mem_test/simple_mem_test.hex + #TODO implement something like sources.list TOP_MODULE=sim_top @@ -15,7 +17,7 @@ all: $(INIT_MEM) iverilog -g2005-sv $(FLAGS) -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS) $(INIT_MEM): - cp ../$(INIT_MEM) . + cp $(TEST_PROGRAM) ./init_hex.mem .PHONY: clean clean: diff --git a/sw/test_code/simple_mem_test/Makefile b/sw/test_code/simple_mem_test/Makefile new file mode 100644 index 0000000..34a0ce9 --- /dev/null +++ b/sw/test_code/simple_mem_test/Makefile @@ -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 + diff --git a/sw/test_code/simple_mem_test/link.ld b/sw/test_code/simple_mem_test/link.ld new file mode 100644 index 0000000..66a42fe --- /dev/null +++ b/sw/test_code/simple_mem_test/link.ld @@ -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 +} diff --git a/sw/test_code/simple_mem_test/main.s b/sw/test_code/simple_mem_test/main.s new file mode 100644 index 0000000..d7ce83d --- /dev/null +++ b/sw/test_code/simple_mem_test/main.s @@ -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 \ No newline at end of file diff --git a/sw/test_code/simple_mem_test/vectors.s b/sw/test_code/simple_mem_test/vectors.s new file mode 100644 index 0000000..81ae6e0 --- /dev/null +++ b/sw/test_code/simple_mem_test/vectors.s @@ -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 \ No newline at end of file From 3fcfa4d3acce50400654000b59bef553996fad17 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 24 Sep 2023 10:34:07 -0700 Subject: [PATCH 11/57] Add REPO_TOP env var --- hw/efinix_fpga/simulation/Makefile | 6 ++++-- hw/efinix_fpga/init_env.sh => init_env.sh | 2 ++ sw/bios/Makefile | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) rename hw/efinix_fpga/init_env.sh => init_env.sh (93%) diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index 520865f..c9e6218 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -4,7 +4,9 @@ SRCS+=$(shell find ../src/ -type f -name "*.*v") INC=$(shell find include/ -type f) -TEST_PROGRAM=../../../sw/test_code/simple_mem_test/simple_mem_test.hex +TEST_PROGRAM_NAME=simple_mem_test + +TEST_PROGRAM=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME)/$(TEST_PROGRAM_NAME).hex #TODO implement something like sources.list @@ -22,4 +24,4 @@ $(INIT_MEM): .PHONY: clean clean: rm -rf $(TARGET) - rm $(INIT_MEM) \ No newline at end of file + rm -rf $(INIT_MEM) \ No newline at end of file diff --git a/hw/efinix_fpga/init_env.sh b/init_env.sh similarity index 93% rename from hw/efinix_fpga/init_env.sh rename to init_env.sh index 22ec0d4..46419d9 100644 --- a/hw/efinix_fpga/init_env.sh +++ b/init_env.sh @@ -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 diff --git a/sw/bios/Makefile b/sw/bios/Makefile index 3a9399a..3d489a2 100644 --- a/sw/bios/Makefile +++ b/sw/bios/Makefile @@ -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 From be68b4c9f930ea106da1b747121a6266c450c7bf Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 24 Sep 2023 14:53:38 -0700 Subject: [PATCH 12/57] Change sdrclk and sysclk to have aligned rising edges --- hw/efinix_fpga/simulation/src/sim_top.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 41bd4f0..bab1306 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -16,7 +16,7 @@ end // clk_200 initial begin - r_sdrclk <= '0; + r_sdrclk <= '1; forever begin #2.5 r_sdrclk <= ~r_sdrclk; end From 95e05292cc1d4edaedc1adb04d7fc460a8b3edea Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 24 Sep 2023 23:58:32 -0700 Subject: [PATCH 13/57] Fix clocks, define RTL_SIM --- hw/efinix_fpga/simulation/Makefile | 2 +- hw/efinix_fpga/simulation/src/sim_top.sv | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index c9e6218..8fc9a76 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -13,7 +13,7 @@ TEST_PROGRAM=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME)/$(TEST_PROGRAM_NAME). TOP_MODULE=sim_top TARGET=sim_top INIT_MEM=init_hex.mem -FLAGS=-DSIM +FLAGS=-DSIM -DRTL_SIM all: $(INIT_MEM) iverilog -g2005-sv $(FLAGS) -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS) diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index bab1306..da53126 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -24,7 +24,7 @@ end // clk_50 initial begin - r_clk_50 <= '0; + r_clk_50 <= '1; forever begin #10 r_clk_50 <= ~r_clk_50; end @@ -32,7 +32,7 @@ end // clk_2 initial begin - r_clk_2 <= '0; + r_clk_2 <= '1; forever begin #250 r_clk_2 <= ~r_clk_2; end @@ -86,7 +86,7 @@ cpu_65c02 u_cpu( super6502 u_dut( .i_sysclk(r_sysclk), .i_sdrclk(r_sdrclk), - .i_tACclk(r_sdrclk), + .i_tACclk(~r_sdrclk), .clk_50(r_clk_50), .clk_2(r_clk_2), .button_reset(button_reset), From 4ee21f23b6c5b574de80a0b4b6a3c11a470f2483 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 25 Sep 2023 19:13:06 -0700 Subject: [PATCH 14/57] Up the sim time --- hw/efinix_fpga/simulation/Makefile | 2 +- hw/efinix_fpga/simulation/src/sim_top.sv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index 8fc9a76..a726e24 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -6,7 +6,7 @@ INC=$(shell find include/ -type f) TEST_PROGRAM_NAME=simple_mem_test -TEST_PROGRAM=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME)/$(TEST_PROGRAM_NAME).hex +TEST_PROGRAM?=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME)/$(TEST_PROGRAM_NAME).hex #TODO implement something like sources.list diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index da53126..80e611e 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -49,7 +49,7 @@ initial begin button_reset <= '0; repeat(10) @(r_clk_2); button_reset <= '1; - repeat(2000) @(r_clk_2); + repeat(8000) @(r_clk_2); $finish(); end From c2dd5d616b2db7cddaf699e9227709a53af15c06 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 25 Sep 2023 23:45:23 -0700 Subject: [PATCH 15/57] Gate rdy behind sdram_cs #28 --- hw/efinix_fpga/simulation/src/sim_top.sv | 4 +++- hw/efinix_fpga/src/sdram_adapter.sv | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 80e611e..6cb4926 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -56,6 +56,7 @@ 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; @@ -64,7 +65,7 @@ cpu_65c02 u_cpu( .phi2(w_cpu_phi2), .reset(~w_cpu_reset), .AB(w_cpu_addr), - .RDY('1), + .RDY(w_cpu_rdy), .IRQ('0), .NMI('0), .DI_s1(w_cpu_data_from_dut), @@ -95,6 +96,7 @@ super6502 u_dut( .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), diff --git a/hw/efinix_fpga/src/sdram_adapter.sv b/hw/efinix_fpga/src/sdram_adapter.sv index f19f706..9b0b7c0 100644 --- a/hw/efinix_fpga/src/sdram_adapter.sv +++ b/hw/efinix_fpga/src/sdram_adapter.sv @@ -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 From 915188e8f1ea9f62443c7caeac34e54646b6f0fb Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 26 Sep 2023 18:23:01 -0700 Subject: [PATCH 16/57] New test program that causes the error --- hw/efinix_fpga/simulation/Makefile | 2 +- sw/test_code/loop_test/Makefile | 39 ++++++++++++++++++++++++++++++ sw/test_code/loop_test/link.ld | 35 +++++++++++++++++++++++++++ sw/test_code/loop_test/main.s | 16 ++++++++++++ sw/test_code/loop_test/vectors.s | 14 +++++++++++ 5 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 sw/test_code/loop_test/Makefile create mode 100644 sw/test_code/loop_test/link.ld create mode 100644 sw/test_code/loop_test/main.s create mode 100644 sw/test_code/loop_test/vectors.s diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index a726e24..773850c 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -4,7 +4,7 @@ SRCS+=$(shell find ../src/ -type f -name "*.*v") INC=$(shell find include/ -type f) -TEST_PROGRAM_NAME=simple_mem_test +TEST_PROGRAM_NAME?=loop_test TEST_PROGRAM?=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME)/$(TEST_PROGRAM_NAME).hex diff --git a/sw/test_code/loop_test/Makefile b/sw/test_code/loop_test/Makefile new file mode 100644 index 0000000..d854069 --- /dev/null +++ b/sw/test_code/loop_test/Makefile @@ -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 + diff --git a/sw/test_code/loop_test/link.ld b/sw/test_code/loop_test/link.ld new file mode 100644 index 0000000..66a42fe --- /dev/null +++ b/sw/test_code/loop_test/link.ld @@ -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 +} diff --git a/sw/test_code/loop_test/main.s b/sw/test_code/loop_test/main.s new file mode 100644 index 0000000..4cd88ca --- /dev/null +++ b/sw/test_code/loop_test/main.s @@ -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 \ No newline at end of file diff --git a/sw/test_code/loop_test/vectors.s b/sw/test_code/loop_test/vectors.s new file mode 100644 index 0000000..81ae6e0 --- /dev/null +++ b/sw/test_code/loop_test/vectors.s @@ -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 \ No newline at end of file From ec4c3bab86f5309db12cffcbe7402533a2ce3b95 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 26 Sep 2023 23:15:22 -0700 Subject: [PATCH 17/57] Update verilog-6502 bslathi19/verilog-6502@aaf4c084ef68b9ee1646dc5acc982820868e090f --- hw/efinix_fpga/simulation/src/verilog-6502 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/verilog-6502 b/hw/efinix_fpga/simulation/src/verilog-6502 index 001840c..aaf4c08 160000 --- a/hw/efinix_fpga/simulation/src/verilog-6502 +++ b/hw/efinix_fpga/simulation/src/verilog-6502 @@ -1 +1 @@ -Subproject commit 001840c64e5bb175672db899009fdea7a815003b +Subproject commit aaf4c084ef68b9ee1646dc5acc982820868e090f From 9e19a1eb72c9e064eb1b10c3f6e8ecd9caba77fe Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 27 Sep 2023 21:14:09 -0700 Subject: [PATCH 18/57] Disable sdr debug, initialize uart status --- hw/efinix_fpga/simulation/src/generic_sdr.v | 2 +- hw/efinix_fpga/simulation/src/sim_top.sv | 2 +- hw/efinix_fpga/src/uart_wrapper.sv | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/efinix_fpga/simulation/src/generic_sdr.v b/hw/efinix_fpga/simulation/src/generic_sdr.v index 06eaa99..8cbcfcb 100644 --- a/hw/efinix_fpga/simulation/src/generic_sdr.v +++ b/hw/efinix_fpga/simulation/src/generic_sdr.v @@ -164,7 +164,7 @@ parameter mem_sizes = 2**(ROW_BITS+COL_BITS) - 1; // Write Burst Mode wire Write_burst_mode = Mode_reg[9]; - wire Debug = 1'b1; // Debug messages : 1 = On + wire Debug = 1'b0; // Debug messages : 1 = On wire Dq_chk = Sys_clk & Data_in_enable; // Check setup/hold time for DQ assign Dq = Dq_reg; // DQ buffer diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 6cb4926..0b9945e 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -49,7 +49,7 @@ initial begin button_reset <= '0; repeat(10) @(r_clk_2); button_reset <= '1; - repeat(8000) @(r_clk_2); + repeat(20000) @(r_clk_2); $finish(); end diff --git a/hw/efinix_fpga/src/uart_wrapper.sv b/hw/efinix_fpga/src/uart_wrapper.sv index 04d35e3..44bd6e1 100644 --- a/hw/efinix_fpga/src/uart_wrapper.sv +++ b/hw/efinix_fpga/src/uart_wrapper.sv @@ -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 From 4d0abbb508dfe225208b443d081097c092e9e71a Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 27 Sep 2023 22:15:27 -0700 Subject: [PATCH 19/57] Add sim uart --- hw/efinix_fpga/simulation/src/sim_top.sv | 163 +++++++++--------- .../simulation/src/sim_uart/sim_uart.sv | 43 +++++ 2 files changed, 125 insertions(+), 81 deletions(-) create mode 100644 hw/efinix_fpga/simulation/src/sim_uart/sim_uart.sv diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 0b9945e..227ae42 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -8,34 +8,34 @@ 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 + 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 + 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 + 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 + r_clk_2 <= '1; + forever begin + #250 r_clk_2 <= ~r_clk_2; + end end initial begin @@ -46,11 +46,11 @@ end logic button_reset; initial begin - button_reset <= '0; - repeat(10) @(r_clk_2); - button_reset <= '1; - repeat(20000) @(r_clk_2); - $finish(); + button_reset <= '0; + repeat(10) @(r_clk_2); + button_reset <= '1; + repeat(20000) @(r_clk_2); + $finish(); end logic w_cpu_reset; @@ -62,53 +62,55 @@ 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) + .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) +); + +logic w_dut_uart_rx, w_dut_uart_tx; + +sim_uart u_sim_uart( + .clk_50(r_clk_50), + .reset(~w_cpu_reset), + .rx_i(w_dut_uart_tx), + .tx_o(w_dut_uart_rx) ); -// 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), + .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), + .uart_rx(w_dut_uart_rx), + .uart_tx(w_dut_uart_tx), + + .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) ); @@ -126,29 +128,28 @@ wire [DQ_GROUP *DQ_WIDTH -1:0]w_sdr_DQ; genvar i, j; generate - for (i=0; i Date: Wed, 27 Sep 2023 23:02:53 -0700 Subject: [PATCH 20/57] Fix uart status multiple drivers --- hw/efinix_fpga/src/uart_wrapper.sv | 35 ++++++++++++++++-------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/hw/efinix_fpga/src/uart_wrapper.sv b/hw/efinix_fpga/src/uart_wrapper.sv index 44bd6e1..3262233 100644 --- a/hw/efinix_fpga/src/uart_wrapper.sv +++ b/hw/efinix_fpga/src/uart_wrapper.sv @@ -48,30 +48,33 @@ always_ff @(posedge clk_50) begin if (reset) begin state <= READY; irqb <= '1; - status <= '0; end else begin state <= next_state; end end always_ff @(negedge clk) begin - status[1] <= tx_busy | tx_en; + if (reset) begin + status <= '0; + end else begin + status[1] <= tx_busy | tx_en; - status[0] <= status[0] | rx_data_valid; - if (cs & ~addr & rwb) begin - status[0] <= 0; - end + status[0] <= status[0] | rx_data_valid; + if (cs & ~addr & rwb) begin + status[0] <= 0; + end - if (cs & ~rwb) begin - case (addr) - 1'b0: begin - tx_data <= i_data; - end + if (cs & ~rwb) begin + case (addr) + 1'b0: begin + tx_data <= i_data; + end - 1'b1: begin - control <= i_data; - end - endcase + 1'b1: begin + control <= i_data; + end + endcase + end end end @@ -80,7 +83,7 @@ always_comb begin case (addr) 1'b0: begin o_data = rx_data; - end + end 1'b1: begin o_data = status; From 85f53816f9c057e527283d54917e2dd947f98bb4 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 27 Sep 2023 23:03:22 -0700 Subject: [PATCH 21/57] Remove unneeded CR --- hw/efinix_fpga/init_hex.mem | 52 ++++++++++++++++++------------------ hw/efinix_fpga/super6502.xml | 2 +- sw/bios/boot2.s | 10 +++---- sw/bios/bootloader.s | 10 +++---- sw/bios/devices/sd_card.c | 8 +++--- sw/bios/devices/sd_print.c | 4 +-- sw/bios/main.c | 10 +++---- sw/kernel/kernel.c | 2 +- 8 files changed, 49 insertions(+), 49 deletions(-) diff --git a/hw/efinix_fpga/init_hex.mem b/hw/efinix_fpga/init_hex.mem index 8d41c16..296024a 100644 --- a/hw/efinix_fpga/init_hex.mem +++ b/hw/efinix_fpga/init_hex.mem @@ -38,32 +38,32 @@ F2 68 60 A9 01 8D DB EF 60 9C DB EF 60 A9 00 8D DA EF AD DB EF 30 FB AD D9 EF 60 8D E6 EF 60 48 8D E6 EF AD E7 EF 89 02 D0 F9 68 60 AD E6 EF A2 00 60 AD E7 EF A2 00 60 60 20 74 FB A2 00 86 06 -86 07 A9 00 20 0B FC 20 5A FB A9 89 A2 FE 20 1A -FB 20 3A F3 C9 00 20 B8 FC D0 03 4C 98 F2 A9 81 -A2 FE 20 1A FB 4C 2E F3 A9 77 A2 FE 20 1A FB A0 +86 07 A9 00 20 0B FC 20 5A FB A9 86 A2 FE 20 1A +FB 20 3A F3 C9 00 20 B8 FC D0 03 4C 98 F2 A9 7F +A2 FE 20 1A FB 4C 2E F3 A9 76 A2 FE 20 1A FB A0 05 20 C7 FB 20 0B FC AD 00 92 AE 01 92 20 4D FD A9 0C 20 D8 FB 20 96 F1 A0 07 91 04 A0 07 A2 00 B1 04 C9 00 20 BE FC D0 03 4C DC F2 A0 06 A2 00 B1 04 C9 FE 20 BE FC F0 03 4C E5 F2 A2 00 A9 00 D0 03 4C E9 F2 A2 00 A9 01 D0 03 4C FA F2 AD 00 92 AE 01 92 20 3C F6 4C 2B F3 A0 06 A2 00 B1 04 -A2 00 29 F0 20 9F FA D0 03 4C 16 F3 A9 81 A2 FE +A2 00 29 F0 20 9F FA D0 03 4C 16 F3 A9 7F A2 FE 20 1A FB 4C 2B F3 A9 67 A2 FE 20 4D FD A0 08 A2 00 B1 04 20 4D FD A0 04 20 E6 FA 6C 00 92 4C 31 F3 4C 31 F3 A0 0C 20 85 FA 60 20 81 FB A9 00 20 37 FD 20 6E F1 4C 71 F3 A0 00 A2 00 18 A9 01 71 04 91 04 A0 00 A2 00 B1 04 C9 FF 20 BE FC D0 03 -4C 71 F3 A9 AB A2 FE 20 1A FB A2 00 A9 01 4C A8 +4C 71 F3 A9 A5 A2 FE 20 1A FB A2 00 A9 01 4C A8 F4 20 AC F4 A0 01 91 04 C9 01 20 B8 FC D0 C9 A2 00 A9 00 A0 06 20 65 FD A0 07 20 BE FB E0 03 D0 02 C9 E8 20 D7 FC F0 03 4C 9E F3 4C AA F3 A0 06 A2 00 A9 01 20 75 FA 4C 88 F3 A9 01 20 D8 FB 20 C9 F4 A0 01 A2 00 B1 04 C9 01 20 B8 FC D0 03 4C -D0 F3 A9 A1 A2 FE 20 1A FB A2 00 A9 01 4C A8 F4 +D0 F3 A9 9C A2 FE 20 1A FB A2 00 A9 01 4C A8 F4 A0 05 A2 00 B1 04 C9 AA 20 B8 FC D0 03 4C E7 F3 A2 00 A9 01 4C A8 F4 A2 00 A9 00 A0 00 91 04 A0 00 A2 00 B1 04 C9 FF 20 BE FC D0 03 4C 0D F4 A9 -91 A2 FE 20 1A FB A2 00 A9 01 4C A8 F4 20 EB F5 +8D A2 FE 20 1A FB A2 00 A9 01 4C A8 F4 20 EB F5 A0 01 91 04 A0 01 A2 00 B1 04 C9 02 20 D7 FC D0 03 4C 2B F4 20 08 F6 A0 01 91 04 A2 00 A9 00 A0 06 20 65 FD A0 07 20 BE FB E0 03 D0 02 C9 E8 20 @@ -101,13 +101,13 @@ A2 00 A9 FF 20 3F F2 20 A4 FB 60 A2 00 A9 37 20 00 B1 04 4C 36 F6 A0 0E 20 85 FA 60 20 4D FD A9 00 20 37 FD 20 5A FB A2 00 A9 00 A0 00 20 65 FD A0 01 20 BE FB E0 02 20 D7 FC F0 03 4C 62 F6 4C -C4 F6 A9 B5 A2 FE 20 4D FD A0 06 20 BE FB A0 00 +C4 F6 A9 AE A2 FE 20 4D FD A0 06 20 BE FB A0 00 20 B3 FB 20 4D FD A0 07 A2 00 A9 01 20 75 FA A0 04 20 E6 FA A0 02 A2 00 B1 04 C9 1F 20 BE FC D0 -03 4C A6 F6 A9 B9 A2 FE 20 1A FB A2 00 A9 00 A0 +03 4C A6 F6 A9 B2 A2 FE 20 1A FB A2 00 A9 00 A0 02 91 04 4C B8 F6 A2 00 A9 20 20 68 F0 A0 02 A2 00 18 A9 01 71 04 91 04 A0 00 A2 00 A9 01 20 75 -FA 4C 50 F6 A9 B9 A2 FE 20 1A FB 20 A9 FB 60 A0 +FA 4C 50 F6 A9 B2 A2 FE 20 1A FB 20 A9 FB 60 A0 00 B1 1A E6 1A D0 02 E6 1B 60 AD 4A 92 8D 45 92 20 7B F7 A9 45 A2 92 20 4D FD 20 2E FD 4C 02 92 A5 18 38 E9 02 85 18 B0 02 C6 19 60 AD 4F 92 D0 @@ -178,8 +178,8 @@ F0 E6 14 D0 EF 60 8C 6A 92 88 88 98 18 65 04 85 20 4D FD A5 0C A6 0D 20 14 FE AC 6A 92 4C 85 FA 85 0C 86 0D 20 75 F0 4C 1E FB 85 0C 86 0D A0 00 B1 0C F0 0E C8 84 14 20 68 F0 A4 14 D0 F2 E6 0D -D0 EE 60 E0 00 D0 15 4A AA BD E3 FE 90 05 4A 4A -4A 4A 18 29 0F AA BD D8 FE A2 00 60 38 A9 00 AA +D0 EE 60 E0 00 D0 15 4A AA BD DB FE 90 05 4A 4A +4A 4A 18 29 0F AA BD D0 FE A2 00 60 38 A9 00 AA 60 A4 04 D0 02 C6 05 C6 04 60 A5 04 38 E9 02 85 04 90 01 60 C6 05 60 A5 04 38 E9 04 85 04 90 01 60 C6 05 60 A5 04 38 E9 06 85 04 90 01 60 C6 05 @@ -196,11 +196,11 @@ A5 06 49 FF 69 00 85 06 A5 07 49 FF 69 00 85 07 91 04 60 85 14 20 8E FB 85 0E 86 0F 85 10 86 11 20 20 FD 20 8E FB 85 06 86 07 60 20 23 FC A6 07 A4 14 C0 0A D0 39 A5 06 05 0D 05 0C D0 11 E0 80 -D0 0D A0 0B B9 CC FE 91 0E 88 10 F8 4C B3 FC 8A +D0 0D A0 0B B9 C4 FE 91 0E 88 10 F8 4C B3 FC 8A 10 1D A9 2D A0 00 91 0E E6 0E D0 02 E6 0F A5 0C A6 0D 20 E4 FB 85 0C 86 0D 4C 7F FC 20 23 FC A9 00 48 A0 20 A9 00 06 0C 26 0D 26 06 26 07 2A C5 -14 90 04 E5 14 E6 0C 88 D0 EC A8 B9 BC FE 48 A5 +14 90 04 E5 14 E6 0C 88 D0 EC A8 B9 B4 FE 48 A5 0C 05 0D 05 06 05 07 D0 D9 A0 00 68 91 0E F0 03 C8 D0 F8 A5 10 A6 11 60 D0 06 A2 00 8A 60 D0 FA A2 00 A9 01 60 F0 F9 30 F7 A2 00 8A 60 F0 02 10 @@ -230,18 +230,18 @@ A0 01 B1 04 AA 88 B1 04 20 4D FD A0 02 A9 2A 91 AE 2B 92 60 A9 32 85 0C A9 92 85 0D A9 00 A8 A2 00 F0 0A 91 0C C8 D0 FB E6 0D CA D0 F6 C0 39 F0 05 91 0C C8 D0 F7 60 62 61 64 20 74 6F 6B 65 6E -3A 20 25 78 0D 0A 00 53 75 63 63 65 73 73 0D 0A -00 45 72 72 6F 72 0D 0A 00 53 74 61 72 74 0D 0A -00 6F 70 5F 63 6F 6E 64 20 65 72 72 6F 72 0D 0A -00 49 46 20 43 6F 6E 64 0D 0A 00 47 6F 20 49 44 -4C 45 0D 0A 00 25 32 78 00 0D 0A 00 30 31 32 33 -34 35 36 37 38 39 41 42 43 44 45 46 2D 32 31 34 -37 34 38 33 36 34 38 00 00 01 02 0C 09 0A 10 40 -50 A0 D0 66 66 66 66 A6 88 88 66 66 66 66 66 66 -66 66 66 09 00 00 00 00 00 00 00 33 33 33 33 33 -00 00 00 50 55 55 25 22 22 22 22 22 22 22 22 22 -02 00 00 40 44 44 14 11 11 11 11 11 11 11 11 11 -01 00 70 00 00 00 00 00 00 00 00 00 00 00 00 00 +3A 20 25 78 0A 00 53 75 63 63 65 73 73 0A 00 45 +72 72 6F 72 0A 00 53 74 61 72 74 0A 00 6F 70 5F +63 6F 6E 64 20 65 72 72 6F 72 0A 00 49 46 20 43 +6F 6E 64 0A 00 47 6F 20 49 44 4C 45 0A 00 25 32 +78 00 0A 00 30 31 32 33 34 35 36 37 38 39 41 42 +43 44 45 46 2D 32 31 34 37 34 38 33 36 34 38 00 +00 01 02 0C 09 0A 10 40 50 A0 D0 66 66 66 66 A6 +88 88 66 66 66 66 66 66 66 66 66 09 00 00 00 00 +00 00 00 33 33 33 33 33 00 00 00 50 55 55 25 22 +22 22 22 22 22 22 22 22 02 00 00 40 44 44 14 11 +11 11 11 11 11 11 11 11 01 00 70 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/hw/efinix_fpga/super6502.xml b/hw/efinix_fpga/super6502.xml index 674cb88..6c9b7fe 100644 --- a/hw/efinix_fpga/super6502.xml +++ b/hw/efinix_fpga/super6502.xml @@ -1,4 +1,4 @@ - + diff --git a/sw/bios/boot2.s b/sw/bios/boot2.s index 920303f..01c14ff 100644 --- a/sw/bios/boot2.s +++ b/sw/bios/boot2.s @@ -335,10 +335,10 @@ _start: @end: bra @end -str: .asciiz "boot2\r\n" +str: .asciiz "boot2\n" kernel_str: .asciiz "KERNEL O65" -_good: .asciiz "Found KERNEL\r\n" -word_str: .asciiz "Word Value: %x\r\n" +_good: .asciiz "Found KERNEL\n" +word_str: .asciiz "Word Value: %x\n" -opt_str: .asciiz "Opt Len: %x, Opt Type: %x\r\n" -opt_done: .asciiz "Options done. total option length: %x\r\n" \ No newline at end of file +opt_str: .asciiz "Opt Len: %x, Opt Type: %x\n" +opt_done: .asciiz "Options done. total option length: %x\n" \ No newline at end of file diff --git a/sw/bios/bootloader.s b/sw/bios/bootloader.s index d928332..da6a20f 100644 --- a/sw/bios/bootloader.s +++ b/sw/bios/bootloader.s @@ -173,12 +173,12 @@ _main: @end: bra @end -str: .asciiz "boot\r\n" +str: .asciiz "boot\n" _boot2_str: .asciiz "BOOT2 BIN" -_fail: .asciiz "not bootloader\r\n" -_good: .asciiz "found bootloader!\r\n" -_cluster: .asciiz "cluster: %lx\r\n" -_addr: .asciiz "addr: %x\r\n" +_fail: .asciiz "not bootloader\n" +_good: .asciiz "found bootloader!\n" +_cluster: .asciiz "cluster: %lx\n" +_addr: .asciiz "addr: %x\n" _end: .res (440+_start-_end) diff --git a/sw/bios/devices/sd_card.c b/sw/bios/devices/sd_card.c index 8eaf708..d1c5b47 100644 --- a/sw/bios/devices/sd_card.c +++ b/sw/bios/devices/sd_card.c @@ -20,7 +20,7 @@ uint8_t SD_init() cmdAttempts++; if(cmdAttempts == CMD0_MAX_ATTEMPTS) { - cputs("Go IDLE\r\n"); + cputs("Go IDLE\n"); return SD_ERROR; } } @@ -30,7 +30,7 @@ uint8_t SD_init() SD_sendIfCond(res); if(res[0] != SD_IN_IDLE_STATE) { - cputs("IF Cond\r\n"); + cputs("IF Cond\n"); return SD_ERROR; } @@ -44,7 +44,7 @@ uint8_t SD_init() { if(cmdAttempts == CMD55_MAX_ATTEMPTS) { - cputs("op_cond error\r\n"); + cputs("op_cond error\n"); return SD_ERROR; } @@ -304,7 +304,7 @@ void SD_sendStatus(uint8_t *res) // while(++readAttempts != SD_MAX_READ_ATTEMPTS) // if((read = spi_exchange(0xFF)) != 0xFF) break; -// cprintf("read attempts: %d\r\n", readAttempts); +// cprintf("read attempts: %d\n", readAttempts); // // if response token is 0xFE // if(read == SD_START_TOKEN) diff --git a/sw/bios/devices/sd_print.c b/sw/bios/devices/sd_print.c index 7e3d305..73f39aa 100644 --- a/sw/bios/devices/sd_print.c +++ b/sw/bios/devices/sd_print.c @@ -13,7 +13,7 @@ void SD_printBuf(uint8_t *buf) cprintf("%2x", *buf++); if(colCount == 31) { - cputs("\r\n"); + cputs("\n"); colCount = 0; } else @@ -22,5 +22,5 @@ void SD_printBuf(uint8_t *buf) colCount++; } } - cputs("\r\n"); + cputs("\n"); } diff --git a/sw/bios/main.c b/sw/bios/main.c index 27a701d..0f7d779 100644 --- a/sw/bios/main.c +++ b/sw/bios/main.c @@ -19,16 +19,16 @@ int main() { uint32_t addr = 0x00000000; uint16_t i; - cputs("Start\r\n"); + cputs("Start\n"); // initialize sd card if(SD_init() != SD_SUCCESS) { - cputs("Error\r\n"); + cputs("Error\n"); } else { - cputs("Success\r\n"); + cputs("Success\n"); res[0] = SD_readSingleBlock(addr, buf, &token); @@ -38,9 +38,9 @@ int main() { //else if error token received, print else if(!(token & 0xF0)) { - cputs("Error\r\n"); + cputs("Error\n"); } else { - cprintf("bad token: %x\r\n", token); + cprintf("bad token: %x\n", token); } __asm__ ("jmp (%v)", buf); diff --git a/sw/kernel/kernel.c b/sw/kernel/kernel.c index 246ce06..2a111a8 100644 --- a/sw/kernel/kernel.c +++ b/sw/kernel/kernel.c @@ -16,7 +16,7 @@ int main() { cprintf("%s", string); - cprintf("Here is a long string: %s\r\n", longstring); + cprintf("Here is a long string: %s\n", longstring); while(1); From 59f88ead3f1cd70c2ff15e22f1db45df58b06055 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Fri, 29 Sep 2023 04:25:54 +0000 Subject: [PATCH 22/57] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..ac44185 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,30 @@ +# This file is a template, and might need editing before it works on your project. +# This is a sample GitLab CI/CD configuration file that should run without any modifications. +# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts, +# it uses echo commands to simulate the pipeline execution. +# +# A pipeline is composed of independent jobs that run scripts, grouped into stages. +# Stages run in sequential order, but jobs within stages run in parallel. +# +# For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages +# +# You can copy and paste this template into a new `.gitlab-ci.yml` file. +# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword. +# +# To contribute improvements to CI/CD templates, please follow the Development guide at: +# https://docs.gitlab.com/ee/development/cicd/templates.html +# This specific template is located at: +# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml + +stages: # List of stages for jobs, and their order of execution + - build + +build-job: # This job runs in the build stage, which runs first. + tags: + - efinity + stage: build + script: + - env + - source init_env.sh + - cd hw/efinix_fpga + - make \ No newline at end of file From d113498459ebc248fbe7dc44db26b001af618f00 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Thu, 28 Sep 2023 21:28:39 -0700 Subject: [PATCH 23/57] Try a bad commit --- hw/efinix_fpga/src/super6502.sv | 2 ++ hw/efinix_fpga/super6502.xml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/efinix_fpga/src/super6502.sv b/hw/efinix_fpga/src/super6502.sv index b0b1a49..bdba1af 100644 --- a/hw/efinix_fpga/src/super6502.sv +++ b/hw/efinix_fpga/src/super6502.sv @@ -56,6 +56,8 @@ assign cpu_nmib = '1; logic w_wait; assign cpu_rdy = ~w_wait; +logic no_semicolon + assign cpu_phi2 = clk_2; logic w_sdr_init_done; diff --git a/hw/efinix_fpga/super6502.xml b/hw/efinix_fpga/super6502.xml index 6c9b7fe..ee7dc15 100644 --- a/hw/efinix_fpga/super6502.xml +++ b/hw/efinix_fpga/super6502.xml @@ -1,4 +1,4 @@ - + From d5bb93f9c937dd1d64ca25e1d17b465e0f5b5b17 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Thu, 28 Sep 2023 21:30:38 -0700 Subject: [PATCH 24/57] Fix the bad commit --- hw/efinix_fpga/src/super6502.sv | 2 -- hw/efinix_fpga/super6502.xml | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/hw/efinix_fpga/src/super6502.sv b/hw/efinix_fpga/src/super6502.sv index bdba1af..b0b1a49 100644 --- a/hw/efinix_fpga/src/super6502.sv +++ b/hw/efinix_fpga/src/super6502.sv @@ -56,8 +56,6 @@ assign cpu_nmib = '1; logic w_wait; assign cpu_rdy = ~w_wait; -logic no_semicolon - assign cpu_phi2 = clk_2; logic w_sdr_init_done; diff --git a/hw/efinix_fpga/super6502.xml b/hw/efinix_fpga/super6502.xml index ee7dc15..ee79774 100644 --- a/hw/efinix_fpga/super6502.xml +++ b/hw/efinix_fpga/super6502.xml @@ -1,4 +1,4 @@ - + From df89962932d636e18c082249ec50c17d0875458d Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Thu, 28 Sep 2023 21:34:42 -0700 Subject: [PATCH 25/57] remove env call --- .gitlab-ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ac44185..ce325bc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,7 +24,6 @@ build-job: # This job runs in the build stage, which runs first. - efinity stage: build script: - - env - source init_env.sh - cd hw/efinix_fpga - - make \ No newline at end of file + - make From 62967aa88de124777139d0972f48e54afe342f96 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Fri, 29 Sep 2023 05:14:52 +0000 Subject: [PATCH 26/57] Resolve "Add build check to CI" --- .gitlab-ci.yml | 19 ++++++++++++++++++- hw/efinix_fpga/simulation/Makefile | 6 ++++-- hw/efinix_fpga/super6502.xml | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ce325bc..f55824e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,14 +16,31 @@ # This specific template is located at: # https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml +variables: + GIT_SUBMODULE_STRATEGY: recursive + stages: # List of stages for jobs, and their order of execution - build -build-job: # This job runs in the build stage, which runs first. +build-fpga: # This job runs in the build stage, which runs first. tags: - efinity + - linux stage: build script: - source init_env.sh - cd hw/efinix_fpga - make + +build-sim: + tags: + - iverilog + - linux + stage: build + script: + - source init_env.sh + - cd sw/cc65 + - make -j + - cd ../.. + - cd hw/efinix_fpga/simulation + - make diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index 773850c..ee67cae 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -5,9 +5,10 @@ SRCS+=$(shell find ../src/ -type f -name "*.*v") INC=$(shell find include/ -type f) TEST_PROGRAM_NAME?=loop_test - +TEST_FOLDER?=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME) TEST_PROGRAM?=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME)/$(TEST_PROGRAM_NAME).hex + #TODO implement something like sources.list TOP_MODULE=sim_top @@ -19,9 +20,10 @@ all: $(INIT_MEM) iverilog -g2005-sv $(FLAGS) -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS) $(INIT_MEM): + $(MAKE) -C $(TEST_FOLDER) cp $(TEST_PROGRAM) ./init_hex.mem .PHONY: clean clean: rm -rf $(TARGET) - rm -rf $(INIT_MEM) \ No newline at end of file + rm -rf $(INIT_MEM) diff --git a/hw/efinix_fpga/super6502.xml b/hw/efinix_fpga/super6502.xml index ee79774..1431efd 100644 --- a/hw/efinix_fpga/super6502.xml +++ b/hw/efinix_fpga/super6502.xml @@ -1,4 +1,4 @@ - + From 913351efd4e2c390e416d2c2e17ffcdec9ea1210 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Thu, 28 Sep 2023 23:09:47 -0700 Subject: [PATCH 27/57] Add sd emulator as submodule --- .gitmodules | 3 +++ hw/efinix_fpga/simulation/src/verilog-sd-emulator | 1 + 2 files changed, 4 insertions(+) create mode 160000 hw/efinix_fpga/simulation/src/verilog-sd-emulator diff --git a/.gitmodules b/.gitmodules index 0a0a7e3..da7e628 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "hw/efinix_fpga/simulation/src/verilog-6502"] path = hw/efinix_fpga/simulation/src/verilog-6502 url = https://git.byronlathi.com/bslathi19/verilog-6502 +[submodule "hw/efinix_fpga/simulation/src/verilog-sd-emulator"] + path = hw/efinix_fpga/simulation/src/verilog-sd-emulator + url = https://git.byronlathi.com/bslathi19/verilog-sd-emulator diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator new file mode 160000 index 0000000..7fb88c9 --- /dev/null +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -0,0 +1 @@ +Subproject commit 7fb88c9ee1ca65dd5bfd10b2e0f6331e958abdd7 From d3d3fea9163ee761e374b69e714afcd0735de289 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sat, 30 Sep 2023 04:16:52 +0000 Subject: [PATCH 28/57] Resolve "Use dependencies instead of makefile chaining" --- .gitlab-ci.yml | 45 ++++++++++++++++--- .gitmodules | 3 ++ .../simulation/src/verilog-sd-emulator | 1 + sw/Makefile | 8 ++-- 4 files changed, 48 insertions(+), 9 deletions(-) create mode 160000 hw/efinix_fpga/simulation/src/verilog-sd-emulator diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f55824e..5b77088 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,9 +20,23 @@ variables: GIT_SUBMODULE_STRATEGY: recursive stages: # List of stages for jobs, and their order of execution + - toolchain - build -build-fpga: # This job runs in the build stage, which runs first. +build toolchain: + tags: + - linux + stage: toolchain + script: + - source init_env.sh + - cd sw/cc65 + - make -j + artifacts: + paths: + - sw/cc65/bin + - sw/cc65/lib + +build fpga: # This job runs in the build stage, which runs first. tags: - efinity - linux @@ -32,15 +46,36 @@ build-fpga: # This job runs in the build stage, which runs first. - cd hw/efinix_fpga - make -build-sim: +build sim: tags: - iverilog - linux stage: build script: - source init_env.sh - - cd sw/cc65 - - make -j - - cd ../.. - cd hw/efinix_fpga/simulation - make + dependencies: + - build toolchain + +build bios: + tags: + - linux + stage: build + script: + - source init_env.sh + - cd sw/ + - make bios + dependencies: + - build toolchain + +build kernel: + tags: + - linux + stage: build + script: + - source init_env.sh + - cd sw/ + - make kernel + dependencies: + - build toolchain \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 0a0a7e3..da7e628 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "hw/efinix_fpga/simulation/src/verilog-6502"] path = hw/efinix_fpga/simulation/src/verilog-6502 url = https://git.byronlathi.com/bslathi19/verilog-6502 +[submodule "hw/efinix_fpga/simulation/src/verilog-sd-emulator"] + path = hw/efinix_fpga/simulation/src/verilog-sd-emulator + url = https://git.byronlathi.com/bslathi19/verilog-sd-emulator diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator new file mode 160000 index 0000000..7fb88c9 --- /dev/null +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -0,0 +1 @@ +Subproject commit 7fb88c9ee1ca65dd5bfd10b2e0f6331e958abdd7 diff --git a/sw/Makefile b/sw/Makefile index c379713..a47ed42 100644 --- a/sw/Makefile +++ b/sw/Makefile @@ -1,6 +1,6 @@ -.PHONY: all install bootloader kernel clean +.PHONY: all install bios kernel clean -all: toolchain bootloader kernel +all: toolchain bios kernel install: all sh script/format_disk.sh @@ -9,8 +9,8 @@ install: all toolchain: @$(MAKE) -j4 -C cc65 -bootloader: - @$(MAKE) -C bootloader +bios: + @$(MAKE) -C bios kernel: @$(MAKE) -C kernel From f8bdbfbb2bccf70d14bec9655c9ace4a1d4fac31 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sat, 30 Sep 2023 05:05:12 +0000 Subject: [PATCH 29/57] Resolve "Run simulation as part of ci" --- .gitlab-ci.yml | 19 ++++++++++++++++++- init_env.sh | 9 +++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5b77088..f66e279 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,6 +22,7 @@ variables: stages: # List of stages for jobs, and their order of execution - toolchain - build + - simulate build toolchain: tags: @@ -51,6 +52,10 @@ build sim: - iverilog - linux stage: build + artifacts: + paths: + - hw/efinix_fpga/simulation/sim_top + - hw/efinix_fpga/simulation/init_hex.mem script: - source init_env.sh - cd hw/efinix_fpga/simulation @@ -78,4 +83,16 @@ build kernel: - cd sw/ - make kernel dependencies: - - build toolchain \ No newline at end of file + - build toolchain + +run sim: + tags: + - linux + - iverilog + stage: simulate + script: + - source init_env.sh + - cd hw/efinix_fpga/simulation + - vvp sim_top + dependencies: + - build sim diff --git a/init_env.sh b/init_env.sh index 46419d9..443f828 100644 --- a/init_env.sh +++ b/init_env.sh @@ -3,6 +3,8 @@ # ENV=".env/$HOSTNAME" +export REPO_TOP=$(git rev-parse --show-toplevel) + # if [ ! -d "$ENV" ]; then # mkdir -p "$ENV" # fi @@ -19,8 +21,11 @@ # source "$ENV/efinity/2023.1/bin/setup.sh" # export PATH=$PATH:"$EFXPT_HOME/bin" -source $EFX_SETUP -export REPO_TOP=$(git rev-parse --show-toplevel) +if [ -n "$EFX_SETUP" ]; then + source $EFX_SETUP +else + echo "EFX_SETUP not defined!" +fi # python -m venv .user_venv --system-site-packages From cc32430f2aaf82a1cf1562c1ef93bda1b0b13da3 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Fri, 29 Sep 2023 23:48:28 -0700 Subject: [PATCH 30/57] Refactor makefile, update verilog-sd-emulator --- .gitlab-ci.yml | 4 ++-- hw/efinix_fpga/simulation/Makefile | 8 +++++++- hw/efinix_fpga/simulation/src/sim_top.sv | 19 ++++++++++++++++++- .../simulation/src/verilog-sd-emulator | 2 +- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f66e279..c9d0041 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -59,7 +59,7 @@ build sim: script: - source init_env.sh - cd hw/efinix_fpga/simulation - - make + - make sim_top dependencies: - build toolchain @@ -93,6 +93,6 @@ run sim: script: - source init_env.sh - cd hw/efinix_fpga/simulation - - vvp sim_top + - make sim dependencies: - build sim diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index ee67cae..a0bb1eb 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -16,7 +16,13 @@ TARGET=sim_top INIT_MEM=init_hex.mem FLAGS=-DSIM -DRTL_SIM -all: $(INIT_MEM) +all: sim + +.PHONY: sim +sim: $(TARGET) + vvp $(TARGET) -fst + +$(TARGET): $(INIT_MEM) $(SRCS) iverilog -g2005-sv $(FLAGS) -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS) $(INIT_MEM): diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 227ae42..f5cafb0 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -49,7 +49,7 @@ initial begin button_reset <= '0; repeat(10) @(r_clk_2); button_reset <= '1; - repeat(20000) @(r_clk_2); + repeat(50000) @(r_clk_2); $finish(); end @@ -82,6 +82,18 @@ sim_uart u_sim_uart( .tx_o(w_dut_uart_rx) ); +logic w_sd_cs; +logic w_spi_clk; +logic w_spi_mosi; +logic w_spi_miso; + +sd_card_emu u_sd_card_emu( + .clk(w_spi_clk), + .cs(w_sd_cs), + .mosi(w_spi_mosi), + .miso(w_spi_miso) +); + super6502 u_dut( .i_sysclk(r_sysclk), @@ -101,6 +113,11 @@ super6502 u_dut( .uart_rx(w_dut_uart_rx), .uart_tx(w_dut_uart_tx), + .sd_cs(w_sd_cs), + .spi_clk(w_spi_clk), + .spi_mosi(w_spi_mosi), + .spi_miso(w_spi_miso), + .o_sdr_CKE(w_sdr_CKE), .o_sdr_n_CS(w_sdr_n_CS), .o_sdr_n_WE(w_sdr_n_WE), diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 7fb88c9..a378570 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 7fb88c9ee1ca65dd5bfd10b2e0f6331e958abdd7 +Subproject commit a37857045c3c070833f2409f1eda81a2af1c6800 From 3a211faed7db3eaf161bf2d8a01777cb50561326 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sat, 30 Sep 2023 17:40:01 -0700 Subject: [PATCH 31/57] Don't have sd wait in simulation need to figure out how to set that RTL_SIM flag only when we are compiling code for the sim also bro the sim is like 8000x slower than irl. --- hw/efinix_fpga/init_hex.mem | 422 +++++++++--------- .../simulation/src/verilog-sd-emulator | 2 +- sw/bios/Makefile | 2 +- sw/bios/devices/sd_card.c | 2 + 4 files changed, 215 insertions(+), 213 deletions(-) diff --git a/hw/efinix_fpga/init_hex.mem b/hw/efinix_fpga/init_hex.mem index 296024a..8b65c22 100644 --- a/hw/efinix_fpga/init_hex.mem +++ b/hw/efinix_fpga/init_hex.mem @@ -1,9 +1,9 @@ @00000000 00 80 4C 00 00 8D 13 92 8E 14 92 8D 1A 92 8E 1B 92 88 B9 FF FF 8D 24 92 88 B9 FF FF 8D 23 92 8C -26 92 20 FF FF A0 FF D0 E8 60 00 00 CC FD 00 00 -00 00 A2 FF 9A D8 A9 00 85 04 A9 DF 85 05 20 44 -FE 20 B9 FA 20 52 F0 58 20 69 F2 6C FC FF 20 AD +26 92 20 FF FF A0 FF D0 E8 60 00 00 A1 FD 00 00 +00 00 A2 FF 9A D8 A9 00 85 04 A9 DF 85 05 20 19 +FE 20 8E FA 20 52 F0 58 20 69 F2 6C FC FF 20 82 FA 00 A0 00 F0 07 A9 52 A2 F0 4C 05 92 60 AD FF EF A2 00 60 8D FF EF 60 20 4F F2 C9 0A D0 05 A9 0D 20 4F F2 60 DA 5A A8 B2 04 AA A9 1B 20 4F F2 @@ -13,19 +13,19 @@ A9 63 20 4F F2 68 60 40 DA BA 48 E8 E8 BD 00 01 29 10 D0 06 68 FA 20 68 F2 40 68 FA 7C BF F0 C5 F0 C9 F0 CA F0 20 9A F0 40 40 20 68 F0 40 48 A0 04 B1 04 09 40 20 3F F2 88 B1 04 20 3F F2 88 10 -F8 68 09 01 20 3F F2 20 A9 FB 60 A2 08 A9 FF 20 +F8 68 09 01 20 3F F2 20 7E FB 60 A2 08 A9 FF 20 3F F2 C9 FF D0 03 CA D0 F4 60 85 0C 86 0D 20 EB -F0 92 0C A9 FF 20 3F F2 A0 01 91 0C 20 96 FB 60 -AA 20 20 FD A9 FF 20 3F F2 92 0C E6 0C D0 02 E6 +F0 92 0C A9 FF 20 3F F2 A0 01 91 0C 20 6B FB 60 +AA 20 F5 FC A9 FF 20 3F F2 92 0C E6 0C D0 02 E6 0D CA D0 F0 60 85 0C 86 0D 20 EB F0 C9 02 B0 12 -E6 0C D0 02 E6 0C A5 0C A6 0D 20 4D FD A9 04 20 +E6 0C D0 02 E6 0C A5 0C A6 0D 20 22 FD A9 04 20 10 F1 60 48 A9 FF 20 3F F2 A9 00 20 33 F2 A9 FF 20 3F F2 68 20 CE F0 20 EB F0 A8 A9 FF 20 3F F2 A9 00 20 39 F2 A9 FF 20 3F F2 98 A2 00 60 A9 00 20 39 F2 20 8B F1 A9 FF 20 3F F2 A9 00 20 39 F2 A2 50 A9 FF 20 3F F2 CA D0 F8 60 A2 01 A9 C8 3A -D0 FD CA D0 F8 60 85 0E 86 0F A9 FF 92 0E 20 20 -FD A5 04 85 10 A5 05 85 11 20 51 FB A0 00 B1 10 +D0 FD CA D0 F8 60 85 0E 86 0F A9 FF 92 0E 20 F5 +FC A5 04 85 10 A5 05 85 11 20 26 FB A0 00 B1 10 91 04 C8 B1 10 91 04 C8 B1 10 91 04 C8 B1 10 91 04 A9 FF 20 3F F2 A9 00 20 33 F2 A9 FF 20 3F F2 A9 11 A0 04 91 04 A9 00 20 CE F0 20 EB F0 C9 FF @@ -37,210 +37,210 @@ EB A9 FF 20 3F F2 A9 FF 20 3F F2 A5 15 92 0E A5 F2 68 60 A9 01 8D DB EF 60 9C DB EF 60 A9 00 8D DA EF AD DB EF 30 FB AD D9 EF 60 8D E6 EF 60 48 8D E6 EF AD E7 EF 89 02 D0 F9 68 60 AD E6 EF A2 -00 60 AD E7 EF A2 00 60 60 20 74 FB A2 00 86 06 -86 07 A9 00 20 0B FC 20 5A FB A9 86 A2 FE 20 1A -FB 20 3A F3 C9 00 20 B8 FC D0 03 4C 98 F2 A9 7F -A2 FE 20 1A FB 4C 2E F3 A9 76 A2 FE 20 1A FB A0 -05 20 C7 FB 20 0B FC AD 00 92 AE 01 92 20 4D FD -A9 0C 20 D8 FB 20 96 F1 A0 07 91 04 A0 07 A2 00 -B1 04 C9 00 20 BE FC D0 03 4C DC F2 A0 06 A2 00 -B1 04 C9 FE 20 BE FC F0 03 4C E5 F2 A2 00 A9 00 +00 60 AD E7 EF A2 00 60 60 20 49 FB A2 00 86 06 +86 07 A9 00 20 E0 FB 20 2F FB A9 5B A2 FE 20 EF +FA 20 3A F3 C9 00 20 8D FC D0 03 4C 98 F2 A9 54 +A2 FE 20 EF FA 4C 2E F3 A9 4B A2 FE 20 EF FA A0 +05 20 9C FB 20 E0 FB AD 00 92 AE 01 92 20 22 FD +A9 0C 20 AD FB 20 96 F1 A0 07 91 04 A0 07 A2 00 +B1 04 C9 00 20 93 FC D0 03 4C DC F2 A0 06 A2 00 +B1 04 C9 FE 20 93 FC F0 03 4C E5 F2 A2 00 A9 00 D0 03 4C E9 F2 A2 00 A9 01 D0 03 4C FA F2 AD 00 -92 AE 01 92 20 3C F6 4C 2B F3 A0 06 A2 00 B1 04 -A2 00 29 F0 20 9F FA D0 03 4C 16 F3 A9 7F A2 FE -20 1A FB 4C 2B F3 A9 67 A2 FE 20 4D FD A0 08 A2 -00 B1 04 20 4D FD A0 04 20 E6 FA 6C 00 92 4C 31 -F3 4C 31 F3 A0 0C 20 85 FA 60 20 81 FB A9 00 20 -37 FD 20 6E F1 4C 71 F3 A0 00 A2 00 18 A9 01 71 -04 91 04 A0 00 A2 00 B1 04 C9 FF 20 BE FC D0 03 -4C 71 F3 A9 A5 A2 FE 20 1A FB A2 00 A9 01 4C A8 -F4 20 AC F4 A0 01 91 04 C9 01 20 B8 FC D0 C9 A2 -00 A9 00 A0 06 20 65 FD A0 07 20 BE FB E0 03 D0 -02 C9 E8 20 D7 FC F0 03 4C 9E F3 4C AA F3 A0 06 -A2 00 A9 01 20 75 FA 4C 88 F3 A9 01 20 D8 FB 20 -C9 F4 A0 01 A2 00 B1 04 C9 01 20 B8 FC D0 03 4C -D0 F3 A9 9C A2 FE 20 1A FB A2 00 A9 01 4C A8 F4 -A0 05 A2 00 B1 04 C9 AA 20 B8 FC D0 03 4C E7 F3 -A2 00 A9 01 4C A8 F4 A2 00 A9 00 A0 00 91 04 A0 -00 A2 00 B1 04 C9 FF 20 BE FC D0 03 4C 0D F4 A9 -8D A2 FE 20 1A FB A2 00 A9 01 4C A8 F4 20 EB F5 -A0 01 91 04 A0 01 A2 00 B1 04 C9 02 20 D7 FC D0 -03 4C 2B F4 20 08 F6 A0 01 91 04 A2 00 A9 00 A0 -06 20 65 FD A0 07 20 BE FB E0 03 D0 02 C9 E8 20 -D7 FC F0 03 4C 4A F4 4C 56 F4 A0 06 A2 00 A9 01 -20 75 FA 4C 34 F4 A0 00 A2 00 18 A9 01 71 04 91 -04 A0 01 A2 00 B1 04 C9 00 20 B8 FC D0 81 A2 00 -A9 00 A0 06 20 65 FD A0 07 20 BE FB E0 03 D0 02 -C9 E8 20 D7 FC F0 03 4C 8D F4 4C 99 F4 A0 06 A2 -00 A9 01 20 75 FA 4C 77 F4 A9 01 20 D8 FB 20 71 -F5 A2 00 A9 00 4C A8 F4 20 AE FB 60 A2 00 A9 00 -20 37 FD A2 00 86 06 86 07 A9 00 20 0B FC A2 00 -A9 94 20 43 F1 4C C8 F4 60 20 4D FD A2 00 A9 FF +92 AE 01 92 20 11 F6 4C 2B F3 A0 06 A2 00 B1 04 +A2 00 29 F0 20 74 FA D0 03 4C 16 F3 A9 54 A2 FE +20 EF FA 4C 2B F3 A9 3C A2 FE 20 22 FD A0 08 A2 +00 B1 04 20 22 FD A0 04 20 BB FA 6C 00 92 4C 31 +F3 4C 31 F3 A0 0C 20 5A FA 60 20 56 FB A9 00 20 +0C FD 20 6E F1 4C 71 F3 A0 00 A2 00 18 A9 01 71 +04 91 04 A0 00 A2 00 B1 04 C9 FF 20 93 FC D0 03 +4C 71 F3 A9 7A A2 FE 20 EF FA A2 00 A9 01 4C 7D +F4 20 81 F4 A0 01 91 04 C9 01 20 8D FC D0 C9 A9 +01 20 AD FB 20 9E F4 A0 01 A2 00 B1 04 C9 01 20 +8D FC D0 03 4C A5 F3 A9 71 A2 FE 20 EF FA A2 00 +A9 01 4C 7D F4 A0 05 A2 00 B1 04 C9 AA 20 8D FC +D0 03 4C BC F3 A2 00 A9 01 4C 7D F4 A2 00 A9 00 +A0 00 91 04 A0 00 A2 00 B1 04 C9 FF 20 93 FC D0 +03 4C E2 F3 A9 62 A2 FE 20 EF FA A2 00 A9 01 4C +7D F4 20 C0 F5 A0 01 91 04 A0 01 A2 00 B1 04 C9 +02 20 AC FC D0 03 4C 00 F4 20 DD F5 A0 01 91 04 +A2 00 A9 00 A0 06 20 3A FD A0 07 20 93 FB E0 03 +D0 02 C9 E8 20 AC FC F0 03 4C 1F F4 4C 2B F4 A0 +06 A2 00 A9 01 20 4A FA 4C 09 F4 A0 00 A2 00 18 +A9 01 71 04 91 04 A0 01 A2 00 B1 04 C9 00 20 8D +FC D0 81 A2 00 A9 00 A0 06 20 3A FD A0 07 20 93 +FB E0 03 D0 02 C9 E8 20 AC FC F0 03 4C 62 F4 4C +6E F4 A0 06 A2 00 A9 01 20 4A FA 4C 4C F4 A9 01 +20 AD FB 20 46 F5 A2 00 A9 00 4C 7D F4 20 83 FB +60 A2 00 A9 00 20 0C FD A2 00 86 06 86 07 A9 00 +20 E0 FB A2 00 A9 94 20 43 F1 4C 9D F4 60 20 22 +FD A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 A2 +00 A9 FF 20 3F F2 A2 00 A9 08 20 0C FD A2 01 A9 +00 85 06 A9 00 85 07 A9 AA 20 E0 FB A2 00 A9 86 +20 CE F0 A0 01 20 93 FB 20 25 F1 A2 00 A9 FF 20 +3F F2 A2 00 A9 00 20 39 F2 A2 00 A9 FF 20 3F F2 +20 6B FB 60 20 22 FD A2 00 A9 FF 20 3F F2 A2 00 +A9 00 20 33 F2 A2 00 A9 FF 20 3F F2 A2 00 A9 0D +20 0C FD A2 00 86 06 86 07 A9 00 20 E0 FB A2 00 +A9 00 20 CE F0 A0 01 20 93 FB 20 FA F0 A2 00 A9 +FF 20 3F F2 A2 00 A9 00 20 39 F2 A2 00 A9 FF 20 +3F F2 20 6B FB 60 20 22 FD 20 26 FB A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 A2 00 A9 FF 20 3F -F2 A2 00 A9 08 20 37 FD A2 01 A9 00 85 06 A9 00 -85 07 A9 AA 20 0B FC A2 00 A9 86 20 CE F0 A0 01 -20 BE FB 20 25 F1 A2 00 A9 FF 20 3F F2 A2 00 A9 -00 20 39 F2 A2 00 A9 FF 20 3F F2 20 96 FB 60 20 -4D FD A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 -A2 00 A9 FF 20 3F F2 A2 00 A9 0D 20 37 FD A2 00 -86 06 86 07 A9 00 20 0B FC A2 00 A9 00 20 CE F0 -A0 01 20 BE FB 20 FA F0 A2 00 A9 FF 20 3F F2 A2 -00 A9 00 20 39 F2 A2 00 A9 FF 20 3F F2 20 96 FB -60 20 4D FD 20 51 FB A2 00 A9 FF 20 3F F2 A2 00 -A9 00 20 33 F2 A2 00 A9 FF 20 3F F2 A0 00 91 04 -A0 00 A2 00 B1 04 C9 FF 20 B8 FC D0 03 4C B1 F5 -4C A3 F5 A2 00 A9 FF 20 3F F2 C9 FF 20 B8 FC D0 -F2 A2 00 A9 3A 20 37 FD A2 00 86 06 86 07 A9 00 -20 0B FC A2 00 A9 00 20 CE F0 A0 02 20 BE FB 20 -25 F1 A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 39 F2 -A2 00 A9 FF 20 3F F2 20 A4 FB 60 A2 00 A9 37 20 -37 FD A2 00 86 06 86 07 A9 00 20 0B FC A2 00 A9 -00 20 43 F1 4C 07 F6 60 A2 00 A9 29 20 37 FD A2 -00 86 06 A9 40 85 07 A9 00 20 0B FC A2 00 A9 00 -20 43 F1 4C 26 F6 60 20 4D FD 20 74 FB A0 03 A2 -00 B1 04 4C 36 F6 A0 0E 20 85 FA 60 20 4D FD A9 -00 20 37 FD 20 5A FB A2 00 A9 00 A0 00 20 65 FD -A0 01 20 BE FB E0 02 20 D7 FC F0 03 4C 62 F6 4C -C4 F6 A9 AE A2 FE 20 4D FD A0 06 20 BE FB A0 00 -20 B3 FB 20 4D FD A0 07 A2 00 A9 01 20 75 FA A0 -04 20 E6 FA A0 02 A2 00 B1 04 C9 1F 20 BE FC D0 -03 4C A6 F6 A9 B2 A2 FE 20 1A FB A2 00 A9 00 A0 -02 91 04 4C B8 F6 A2 00 A9 20 20 68 F0 A0 02 A2 -00 18 A9 01 71 04 91 04 A0 00 A2 00 A9 01 20 75 -FA 4C 50 F6 A9 B2 A2 FE 20 1A FB 20 A9 FB 60 A0 -00 B1 1A E6 1A D0 02 E6 1B 60 AD 4A 92 8D 45 92 -20 7B F7 A9 45 A2 92 20 4D FD 20 2E FD 4C 02 92 -A5 18 38 E9 02 85 18 B0 02 C6 19 60 AD 4F 92 D0 -11 20 19 F7 4C 98 FA AD 4F 92 D0 06 20 19 F7 4C -92 FA 20 19 F7 85 06 86 07 20 F0 F6 A0 01 B1 18 -AA 88 B1 18 60 A0 00 84 0C 84 0D B1 1A 38 E9 30 -90 2C C9 0A B0 28 20 D3 F6 48 A5 0C A6 0D 06 0C -26 0D 06 0C 26 0D 65 0C 85 0C 8A 65 0D 85 0D 06 -0C 26 0D 68 65 0C 85 0C 90 D1 E6 0D B0 CD A5 0C -A6 0D 60 AC 51 92 EE 51 92 99 52 92 60 A9 52 A2 -92 18 6D 51 92 90 01 E8 4C 4D FD A5 1C A6 1D 4C -4D FD 20 DA F6 EE 4B 92 D0 F8 EE 4C 92 D0 F3 60 -20 7B F7 AD 66 92 AE 67 92 20 4D FD AD 68 92 AE -69 92 20 4D FD 4C 02 92 84 0C 20 0B FC 20 6D F7 -A5 0C 4C 3B FC 84 0C 20 0B FC 20 6D F7 A5 0C 4C -7C FC 48 A0 05 B9 18 00 99 3F 92 88 10 F7 68 85 -18 86 19 20 8E FB 85 1A 86 1B 20 8E FB 85 1C 86 -1D A9 00 A8 91 1C C8 91 1C C8 B1 1C 8D 03 92 C8 -B1 1C 8D 04 92 A5 1A 85 0C A5 1B 85 0D A0 00 B1 -1A F0 0B C9 25 F0 07 C8 D0 F5 E6 1B D0 F1 98 18 -65 1A 85 1A 90 02 E6 1B 38 E5 0C 85 0E A5 1B E5 -0D 85 0F 05 0E F0 25 20 74 FB A0 05 A5 1D 91 04 -88 A5 1C 91 04 88 A5 0D 91 04 88 A5 0C 91 04 88 -A5 0F 91 04 88 A5 0E 91 04 20 02 92 20 CF F6 AA -D0 0B A2 05 BD 3F 92 95 18 CA 10 F8 60 C9 25 D0 -09 B1 1A C9 25 D0 09 20 D3 F6 20 DD F6 4C F5 F7 -A9 00 A2 0B 9D 46 92 CA 10 FA B1 1A C9 2D D0 05 -8E 46 92 F0 19 C9 2B D0 05 8E 47 92 F0 10 C9 20 -D0 05 8E 48 92 F0 07 C9 23 D0 09 8E 49 92 20 D3 -F6 4C 7A F8 A2 20 C9 30 D0 06 AA 20 D3 F6 B1 1A -8E 4A 92 C9 2A D0 09 20 D3 F6 20 19 F7 4C C3 F8 -20 25 F7 8D 4B 92 8E 4C 92 8C 4D 92 8C 4E 92 B1 -1A C9 2E D0 1B 20 D3 F6 B1 1A C9 2A D0 09 20 D3 -F6 20 19 F7 4C EA F8 20 25 F7 8D 4D 92 8E 4E 92 -B1 1A C9 7A F0 19 C9 68 F0 15 C9 74 F0 11 C9 6A -F0 08 C9 4C F0 04 C9 6C D0 0B A9 FF 8D 4F 92 20 -D3 F6 4C F0 F8 8C 51 92 A2 52 8E 66 92 A2 92 8E -67 92 20 D3 F6 C9 63 D0 0D 20 19 F7 8D 52 92 A2 -00 A9 01 4C 1C FA C9 64 F0 04 C9 69 D0 2D A2 00 -AD 48 92 F0 02 A2 20 AD 47 92 F0 02 A2 2B 8E 50 -92 20 07 F7 A4 07 30 0B AC 50 92 F0 06 8C 52 92 -EE 51 92 A0 0A 20 A8 F7 4C 13 FA C9 6E D0 15 20 -19 F7 85 0C 86 0D A0 00 B1 1C 91 0C C8 B1 1C 91 -0C 4C F5 F7 C9 6F D0 27 20 07 F7 AC 49 92 F0 17 -48 86 14 05 14 05 06 05 07 0D 4D 92 0D 4E 92 F0 -06 A9 30 20 63 F7 68 A0 08 20 A8 F7 4C 13 FA C9 -70 D0 0D A2 00 8E 4F 92 E8 8E 49 92 A9 78 D0 27 -C9 73 D0 0C 20 19 F7 8D 66 92 8E 67 92 4C 13 FA -C9 75 D0 0B 20 FC F6 A0 0A 20 B5 F7 4C 13 FA C9 -78 F0 04 C9 58 D0 29 48 AD 49 92 F0 0A A9 30 20 -63 F7 A9 58 20 63 F7 20 FC F6 A0 10 20 B5 F7 68 -C9 78 D0 09 AD 66 92 AE 67 92 20 A5 FD 4C 13 FA -4C F5 F7 AD 66 92 AE 67 92 20 8F FD 8D 68 92 8E -69 92 AD 4D 92 0D 4E 92 F0 15 AE 4D 92 EC 68 92 -AD 4E 92 A8 ED 69 92 B0 06 8E 68 92 8C 69 92 38 -AD 4B 92 ED 68 92 AA AD 4C 92 ED 69 92 B0 03 A9 -00 AA 49 FF 8D 4C 92 8A 49 FF 8D 4B 92 AD 46 92 -D0 03 20 85 F7 20 90 F7 AD 46 92 F0 03 20 85 F7 -4C F5 F7 A0 00 18 71 04 91 04 48 C8 8A 71 04 91 -04 AA 68 60 C8 48 18 98 65 04 85 04 90 02 E6 05 -68 60 A0 FF E0 80 B0 02 A0 00 84 06 84 07 60 E0 -00 D0 06 AA D0 03 A9 01 60 A2 00 8A 60 A0 00 F0 -07 A9 52 A2 F0 4C 05 92 60 A9 00 85 0C A9 F0 85 -0D A9 00 85 0E A9 92 85 0F A2 CD A9 FF 85 14 A0 -00 E8 F0 0D B1 0C 91 0E C8 D0 F6 E6 0D E6 0F D0 -F0 E6 14 D0 EF 60 8C 6A 92 88 88 98 18 65 04 85 -0C A6 05 90 01 E8 86 0D A0 01 B1 0C AA 88 B1 0C -20 4D FD A5 0C A6 0D 20 14 FE AC 6A 92 4C 85 FA -85 0C 86 0D 20 75 F0 4C 1E FB 85 0C 86 0D A0 00 -B1 0C F0 0E C8 84 14 20 68 F0 A4 14 D0 F2 E6 0D -D0 EE 60 E0 00 D0 15 4A AA BD DB FE 90 05 4A 4A -4A 4A 18 29 0F AA BD D0 FE A2 00 60 38 A9 00 AA -60 A4 04 D0 02 C6 05 C6 04 60 A5 04 38 E9 02 85 -04 90 01 60 C6 05 60 A5 04 38 E9 04 85 04 90 01 -60 C6 05 60 A5 04 38 E9 06 85 04 90 01 60 C6 05 -60 A5 04 38 E9 07 85 04 90 01 60 C6 05 60 A0 01 -B1 04 AA 88 B1 04 E6 04 F0 05 E6 04 F0 03 60 E6 -04 E6 05 60 A0 03 4C 85 FA A0 05 4C 85 FA A0 08 -4C 85 FA 85 0C 86 0D A2 00 B1 0C 60 A0 01 B1 04 -AA 88 B1 04 60 A0 03 B1 04 85 07 88 B1 04 85 06 -88 B1 04 AA 88 B1 04 60 A2 00 18 65 04 48 8A 65 -05 AA 68 60 18 49 FF 69 01 48 8A 49 FF 69 00 AA -A5 06 49 FF 69 00 85 06 A5 07 49 FF 69 00 85 07 -68 60 A9 00 AA A0 00 84 06 84 07 48 20 67 FB A0 -03 A5 07 91 04 88 A5 06 91 04 88 8A 91 04 68 88 -91 04 60 85 14 20 8E FB 85 0E 86 0F 85 10 86 11 -20 20 FD 20 8E FB 85 06 86 07 60 20 23 FC A6 07 -A4 14 C0 0A D0 39 A5 06 05 0D 05 0C D0 11 E0 80 -D0 0D A0 0B B9 C4 FE 91 0E 88 10 F8 4C B3 FC 8A -10 1D A9 2D A0 00 91 0E E6 0E D0 02 E6 0F A5 0C -A6 0D 20 E4 FB 85 0C 86 0D 4C 7F FC 20 23 FC A9 -00 48 A0 20 A9 00 06 0C 26 0D 26 06 26 07 2A C5 -14 90 04 E5 14 E6 0C 88 D0 EC A8 B9 B4 FE 48 A5 -0C 05 0D 05 06 05 07 D0 D9 A0 00 68 91 0E F0 03 -C8 D0 F8 A5 10 A6 11 60 D0 06 A2 00 8A 60 D0 FA -A2 00 A9 01 60 F0 F9 30 F7 A2 00 8A 60 F0 02 10 -EF A2 00 8A 60 F0 E9 90 E7 A2 00 8A 60 F0 DB A2 -00 8A 2A 60 20 0D FD A6 11 F0 13 B1 0C 91 0E C8 -B1 0C 91 0E C8 D0 F4 E6 0D E6 0F CA D0 ED A6 10 -F0 08 B1 0C 91 0E C8 CA D0 F8 4C 8E FB 85 10 86 -11 20 20 FD C8 B1 04 AA 86 0F 88 B1 04 85 0E 60 -A0 01 B1 04 85 0D 88 B1 04 85 0C 4C 96 FB A9 01 -4C 4B FD A0 00 B1 04 A4 04 F0 07 C6 04 A0 00 91 -04 60 C6 05 C6 04 91 04 60 A9 00 A2 00 48 A5 04 -38 E9 02 85 04 B0 02 C6 05 A0 01 8A 91 04 68 88 -91 04 60 A0 00 91 04 C8 48 8A 91 04 68 60 85 0E -86 0F 20 20 FD B1 0C D1 0E D0 0C AA F0 10 C8 D0 -F4 E6 0D E6 0F D0 EE B0 03 A2 FF 60 A2 01 60 85 -0E 86 0F A2 00 A0 00 B1 0E F0 08 C8 D0 F9 E6 0F -E8 D0 F4 98 60 85 0C 86 0D 85 0E 86 0F A0 00 B1 -0C F0 14 20 37 FB 29 02 F0 06 B1 0C 69 20 91 0C -C8 D0 EC E6 0D D0 E8 A5 0E A6 0F 60 20 8E FB 85 -0E 86 0F E8 8E 31 92 AA E8 8E 30 92 20 20 FD 20 -8E FB 85 10 86 11 A0 00 84 14 B1 10 18 65 0E 91 -10 C8 B1 10 65 0F 91 10 CE 30 92 F0 11 A4 14 B1 -0C C8 D0 02 E6 0D 84 14 20 68 F0 4C F8 FD CE 31 -92 D0 EA 60 85 0C 86 0D A9 00 8D 2A 92 8D 2B 92 -A0 01 B1 04 AA 88 B1 04 20 4D FD A0 02 A9 2A 91 -04 C8 A9 92 91 04 A5 0C A6 0D 20 C2 F7 AD 2A 92 -AE 2B 92 60 A9 32 85 0C A9 92 85 0D A9 00 A8 A2 -00 F0 0A 91 0C C8 D0 FB E6 0D CA D0 F6 C0 39 F0 -05 91 0C C8 D0 F7 60 62 61 64 20 74 6F 6B 65 6E -3A 20 25 78 0A 00 53 75 63 63 65 73 73 0A 00 45 -72 72 6F 72 0A 00 53 74 61 72 74 0A 00 6F 70 5F -63 6F 6E 64 20 65 72 72 6F 72 0A 00 49 46 20 43 -6F 6E 64 0A 00 47 6F 20 49 44 4C 45 0A 00 25 32 -78 00 0A 00 30 31 32 33 34 35 36 37 38 39 41 42 -43 44 45 46 2D 32 31 34 37 34 38 33 36 34 38 00 -00 01 02 0C 09 0A 10 40 50 A0 D0 66 66 66 66 A6 -88 88 66 66 66 66 66 66 66 66 66 09 00 00 00 00 -00 00 00 33 33 33 33 33 00 00 00 50 55 55 25 22 -22 22 22 22 22 22 22 22 02 00 00 40 44 44 14 11 -11 11 11 11 11 11 11 11 01 00 70 00 00 00 00 00 +F2 A0 00 91 04 A0 00 A2 00 B1 04 C9 FF 20 8D FC +D0 03 4C 86 F5 4C 78 F5 A2 00 A9 FF 20 3F F2 C9 +FF 20 8D FC D0 F2 A2 00 A9 3A 20 0C FD A2 00 86 +06 86 07 A9 00 20 E0 FB A2 00 A9 00 20 CE F0 A0 +02 20 93 FB 20 25 F1 A2 00 A9 FF 20 3F F2 A2 00 +A9 00 20 39 F2 A2 00 A9 FF 20 3F F2 20 79 FB 60 +A2 00 A9 37 20 0C FD A2 00 86 06 86 07 A9 00 20 +E0 FB A2 00 A9 00 20 43 F1 4C DC F5 60 A2 00 A9 +29 20 0C FD A2 00 86 06 A9 40 85 07 A9 00 20 E0 +FB A2 00 A9 00 20 43 F1 4C FB F5 60 20 22 FD 20 +49 FB A0 03 A2 00 B1 04 4C 0B F6 A0 0E 20 5A FA +60 20 22 FD A9 00 20 0C FD 20 2F FB A2 00 A9 00 +A0 00 20 3A FD A0 01 20 93 FB E0 02 20 AC FC F0 +03 4C 37 F6 4C 99 F6 A9 83 A2 FE 20 22 FD A0 06 +20 93 FB A0 00 20 88 FB 20 22 FD A0 07 A2 00 A9 +01 20 4A FA A0 04 20 BB FA A0 02 A2 00 B1 04 C9 +1F 20 93 FC D0 03 4C 7B F6 A9 87 A2 FE 20 EF FA +A2 00 A9 00 A0 02 91 04 4C 8D F6 A2 00 A9 20 20 +68 F0 A0 02 A2 00 18 A9 01 71 04 91 04 A0 00 A2 +00 A9 01 20 4A FA 4C 25 F6 A9 87 A2 FE 20 EF FA +20 7E FB 60 A0 00 B1 1A E6 1A D0 02 E6 1B 60 AD +4A 92 8D 45 92 20 50 F7 A9 45 A2 92 20 22 FD 20 +03 FD 4C 02 92 A5 18 38 E9 02 85 18 B0 02 C6 19 +60 AD 4F 92 D0 11 20 EE F6 4C 6D FA AD 4F 92 D0 +06 20 EE F6 4C 67 FA 20 EE F6 85 06 86 07 20 C5 +F6 A0 01 B1 18 AA 88 B1 18 60 A0 00 84 0C 84 0D +B1 1A 38 E9 30 90 2C C9 0A B0 28 20 A8 F6 48 A5 +0C A6 0D 06 0C 26 0D 06 0C 26 0D 65 0C 85 0C 8A +65 0D 85 0D 06 0C 26 0D 68 65 0C 85 0C 90 D1 E6 +0D B0 CD A5 0C A6 0D 60 AC 51 92 EE 51 92 99 52 +92 60 A9 52 A2 92 18 6D 51 92 90 01 E8 4C 22 FD +A5 1C A6 1D 4C 22 FD 20 AF F6 EE 4B 92 D0 F8 EE +4C 92 D0 F3 60 20 50 F7 AD 66 92 AE 67 92 20 22 +FD AD 68 92 AE 69 92 20 22 FD 4C 02 92 84 0C 20 +E0 FB 20 42 F7 A5 0C 4C 10 FC 84 0C 20 E0 FB 20 +42 F7 A5 0C 4C 51 FC 48 A0 05 B9 18 00 99 3F 92 +88 10 F7 68 85 18 86 19 20 63 FB 85 1A 86 1B 20 +63 FB 85 1C 86 1D A9 00 A8 91 1C C8 91 1C C8 B1 +1C 8D 03 92 C8 B1 1C 8D 04 92 A5 1A 85 0C A5 1B +85 0D A0 00 B1 1A F0 0B C9 25 F0 07 C8 D0 F5 E6 +1B D0 F1 98 18 65 1A 85 1A 90 02 E6 1B 38 E5 0C +85 0E A5 1B E5 0D 85 0F 05 0E F0 25 20 49 FB A0 +05 A5 1D 91 04 88 A5 1C 91 04 88 A5 0D 91 04 88 +A5 0C 91 04 88 A5 0F 91 04 88 A5 0E 91 04 20 02 +92 20 A4 F6 AA D0 0B A2 05 BD 3F 92 95 18 CA 10 +F8 60 C9 25 D0 09 B1 1A C9 25 D0 09 20 A8 F6 20 +B2 F6 4C CA F7 A9 00 A2 0B 9D 46 92 CA 10 FA B1 +1A C9 2D D0 05 8E 46 92 F0 19 C9 2B D0 05 8E 47 +92 F0 10 C9 20 D0 05 8E 48 92 F0 07 C9 23 D0 09 +8E 49 92 20 A8 F6 4C 4F F8 A2 20 C9 30 D0 06 AA +20 A8 F6 B1 1A 8E 4A 92 C9 2A D0 09 20 A8 F6 20 +EE F6 4C 98 F8 20 FA F6 8D 4B 92 8E 4C 92 8C 4D +92 8C 4E 92 B1 1A C9 2E D0 1B 20 A8 F6 B1 1A C9 +2A D0 09 20 A8 F6 20 EE F6 4C BF F8 20 FA F6 8D +4D 92 8E 4E 92 B1 1A C9 7A F0 19 C9 68 F0 15 C9 +74 F0 11 C9 6A F0 08 C9 4C F0 04 C9 6C D0 0B A9 +FF 8D 4F 92 20 A8 F6 4C C5 F8 8C 51 92 A2 52 8E +66 92 A2 92 8E 67 92 20 A8 F6 C9 63 D0 0D 20 EE +F6 8D 52 92 A2 00 A9 01 4C F1 F9 C9 64 F0 04 C9 +69 D0 2D A2 00 AD 48 92 F0 02 A2 20 AD 47 92 F0 +02 A2 2B 8E 50 92 20 DC F6 A4 07 30 0B AC 50 92 +F0 06 8C 52 92 EE 51 92 A0 0A 20 7D F7 4C E8 F9 +C9 6E D0 15 20 EE F6 85 0C 86 0D A0 00 B1 1C 91 +0C C8 B1 1C 91 0C 4C CA F7 C9 6F D0 27 20 DC F6 +AC 49 92 F0 17 48 86 14 05 14 05 06 05 07 0D 4D +92 0D 4E 92 F0 06 A9 30 20 38 F7 68 A0 08 20 7D +F7 4C E8 F9 C9 70 D0 0D A2 00 8E 4F 92 E8 8E 49 +92 A9 78 D0 27 C9 73 D0 0C 20 EE F6 8D 66 92 8E +67 92 4C E8 F9 C9 75 D0 0B 20 D1 F6 A0 0A 20 8A +F7 4C E8 F9 C9 78 F0 04 C9 58 D0 29 48 AD 49 92 +F0 0A A9 30 20 38 F7 A9 58 20 38 F7 20 D1 F6 A0 +10 20 8A F7 68 C9 78 D0 09 AD 66 92 AE 67 92 20 +7A FD 4C E8 F9 4C CA F7 AD 66 92 AE 67 92 20 64 +FD 8D 68 92 8E 69 92 AD 4D 92 0D 4E 92 F0 15 AE +4D 92 EC 68 92 AD 4E 92 A8 ED 69 92 B0 06 8E 68 +92 8C 69 92 38 AD 4B 92 ED 68 92 AA AD 4C 92 ED +69 92 B0 03 A9 00 AA 49 FF 8D 4C 92 8A 49 FF 8D +4B 92 AD 46 92 D0 03 20 5A F7 20 65 F7 AD 46 92 +F0 03 20 5A F7 4C CA F7 A0 00 18 71 04 91 04 48 +C8 8A 71 04 91 04 AA 68 60 C8 48 18 98 65 04 85 +04 90 02 E6 05 68 60 A0 FF E0 80 B0 02 A0 00 84 +06 84 07 60 E0 00 D0 06 AA D0 03 A9 01 60 A2 00 +8A 60 A0 00 F0 07 A9 52 A2 F0 4C 05 92 60 A9 00 +85 0C A9 F0 85 0D A9 00 85 0E A9 92 85 0F A2 CD +A9 FF 85 14 A0 00 E8 F0 0D B1 0C 91 0E C8 D0 F6 +E6 0D E6 0F D0 F0 E6 14 D0 EF 60 8C 6A 92 88 88 +98 18 65 04 85 0C A6 05 90 01 E8 86 0D A0 01 B1 +0C AA 88 B1 0C 20 22 FD A5 0C A6 0D 20 E9 FD AC +6A 92 4C 5A FA 85 0C 86 0D 20 75 F0 4C F3 FA 85 +0C 86 0D A0 00 B1 0C F0 0E C8 84 14 20 68 F0 A4 +14 D0 F2 E6 0D D0 EE 60 E0 00 D0 15 4A AA BD B0 +FE 90 05 4A 4A 4A 4A 18 29 0F AA BD A5 FE A2 00 +60 38 A9 00 AA 60 A4 04 D0 02 C6 05 C6 04 60 A5 +04 38 E9 02 85 04 90 01 60 C6 05 60 A5 04 38 E9 +04 85 04 90 01 60 C6 05 60 A5 04 38 E9 06 85 04 +90 01 60 C6 05 60 A5 04 38 E9 07 85 04 90 01 60 +C6 05 60 A0 01 B1 04 AA 88 B1 04 E6 04 F0 05 E6 +04 F0 03 60 E6 04 E6 05 60 A0 03 4C 5A FA A0 05 +4C 5A FA A0 08 4C 5A FA 85 0C 86 0D A2 00 B1 0C +60 A0 01 B1 04 AA 88 B1 04 60 A0 03 B1 04 85 07 +88 B1 04 85 06 88 B1 04 AA 88 B1 04 60 A2 00 18 +65 04 48 8A 65 05 AA 68 60 18 49 FF 69 01 48 8A +49 FF 69 00 AA A5 06 49 FF 69 00 85 06 A5 07 49 +FF 69 00 85 07 68 60 A9 00 AA A0 00 84 06 84 07 +48 20 3C FB A0 03 A5 07 91 04 88 A5 06 91 04 88 +8A 91 04 68 88 91 04 60 85 14 20 63 FB 85 0E 86 +0F 85 10 86 11 20 F5 FC 20 63 FB 85 06 86 07 60 +20 F8 FB A6 07 A4 14 C0 0A D0 39 A5 06 05 0D 05 +0C D0 11 E0 80 D0 0D A0 0B B9 99 FE 91 0E 88 10 +F8 4C 88 FC 8A 10 1D A9 2D A0 00 91 0E E6 0E D0 +02 E6 0F A5 0C A6 0D 20 B9 FB 85 0C 86 0D 4C 54 +FC 20 F8 FB A9 00 48 A0 20 A9 00 06 0C 26 0D 26 +06 26 07 2A C5 14 90 04 E5 14 E6 0C 88 D0 EC A8 +B9 89 FE 48 A5 0C 05 0D 05 06 05 07 D0 D9 A0 00 +68 91 0E F0 03 C8 D0 F8 A5 10 A6 11 60 D0 06 A2 +00 8A 60 D0 FA A2 00 A9 01 60 F0 F9 30 F7 A2 00 +8A 60 F0 02 10 EF A2 00 8A 60 F0 E9 90 E7 A2 00 +8A 60 F0 DB A2 00 8A 2A 60 20 E2 FC A6 11 F0 13 +B1 0C 91 0E C8 B1 0C 91 0E C8 D0 F4 E6 0D E6 0F +CA D0 ED A6 10 F0 08 B1 0C 91 0E C8 CA D0 F8 4C +63 FB 85 10 86 11 20 F5 FC C8 B1 04 AA 86 0F 88 +B1 04 85 0E 60 A0 01 B1 04 85 0D 88 B1 04 85 0C +4C 6B FB A9 01 4C 20 FD A0 00 B1 04 A4 04 F0 07 +C6 04 A0 00 91 04 60 C6 05 C6 04 91 04 60 A9 00 +A2 00 48 A5 04 38 E9 02 85 04 B0 02 C6 05 A0 01 +8A 91 04 68 88 91 04 60 A0 00 91 04 C8 48 8A 91 +04 68 60 85 0E 86 0F 20 F5 FC B1 0C D1 0E D0 0C +AA F0 10 C8 D0 F4 E6 0D E6 0F D0 EE B0 03 A2 FF +60 A2 01 60 85 0E 86 0F A2 00 A0 00 B1 0E F0 08 +C8 D0 F9 E6 0F E8 D0 F4 98 60 85 0C 86 0D 85 0E +86 0F A0 00 B1 0C F0 14 20 0C FB 29 02 F0 06 B1 +0C 69 20 91 0C C8 D0 EC E6 0D D0 E8 A5 0E A6 0F +60 20 63 FB 85 0E 86 0F E8 8E 31 92 AA E8 8E 30 +92 20 F5 FC 20 63 FB 85 10 86 11 A0 00 84 14 B1 +10 18 65 0E 91 10 C8 B1 10 65 0F 91 10 CE 30 92 +F0 11 A4 14 B1 0C C8 D0 02 E6 0D 84 14 20 68 F0 +4C CD FD CE 31 92 D0 EA 60 85 0C 86 0D A9 00 8D +2A 92 8D 2B 92 A0 01 B1 04 AA 88 B1 04 20 22 FD +A0 02 A9 2A 91 04 C8 A9 92 91 04 A5 0C A6 0D 20 +97 F7 AD 2A 92 AE 2B 92 60 A9 32 85 0C A9 92 85 +0D A9 00 A8 A2 00 F0 0A 91 0C C8 D0 FB E6 0D CA +D0 F6 C0 39 F0 05 91 0C C8 D0 F7 60 62 61 64 20 +74 6F 6B 65 6E 3A 20 25 78 0A 00 53 75 63 63 65 +73 73 0A 00 45 72 72 6F 72 0A 00 53 74 61 72 74 +0A 00 6F 70 5F 63 6F 6E 64 20 65 72 72 6F 72 0A +00 49 46 20 43 6F 6E 64 0A 00 47 6F 20 49 44 4C +45 0A 00 25 32 78 00 0A 00 30 31 32 33 34 35 36 +37 38 39 41 42 43 44 45 46 2D 32 31 34 37 34 38 +33 36 34 38 00 00 01 02 0C 09 0A 10 40 50 A0 D0 +66 66 66 66 A6 88 88 66 66 66 66 66 66 66 66 66 +09 00 00 00 00 00 00 00 33 33 33 33 33 00 00 00 +50 55 55 25 22 22 22 22 22 22 22 22 22 02 00 00 +40 44 44 14 11 11 11 11 11 11 11 11 11 01 00 70 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index a378570..2fc0f07 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit a37857045c3c070833f2409f1eda81a2af1c6800 +Subproject commit 2fc0f0737cb9803e9c127c4a269aacfef24d3f05 diff --git a/sw/bios/Makefile b/sw/bios/Makefile index 3d489a2..f35b1a5 100644 --- a/sw/bios/Makefile +++ b/sw/bios/Makefile @@ -1,5 +1,5 @@ CC=../cc65/bin/cl65 -CFLAGS=-T -t none -I. --cpu "65C02" +CFLAGS=-T -t none -I. --cpu "65C02" -DRTL_SIM LDFLAGS=-C link.ld -m $(NAME).map NAME=bios diff --git a/sw/bios/devices/sd_card.c b/sw/bios/devices/sd_card.c index d1c5b47..404bb7a 100644 --- a/sw/bios/devices/sd_card.c +++ b/sw/bios/devices/sd_card.c @@ -25,7 +25,9 @@ uint8_t SD_init() } } +#ifndef RTL_SIM for (i = 0; i < 1000; i++); +#endif SD_sendIfCond(res); if(res[0] != SD_IN_IDLE_STATE) From c1f7b33dda9380bc77fb83c49757a7cec874ee0b Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 3 Oct 2023 23:08:56 -0700 Subject: [PATCH 32/57] Update sd card emu --- hw/efinix_fpga/simulation/src/verilog-sd-emulator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 2fc0f07..27a4e5d 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 2fc0f0737cb9803e9c127c4a269aacfef24d3f05 +Subproject commit 27a4e5dd87e61ef84f13ea614d0b4ed3293c85c0 From 019b9c812093a249fcb0af91bc06ec2005b2001b Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 4 Oct 2023 19:11:45 -0700 Subject: [PATCH 33/57] Update sd, remove wait state --- hw/efinix_fpga/init_hex.mem | 416 +++++++++--------- hw/efinix_fpga/simulation/src/sim_top.sv | 1 + .../simulation/src/verilog-sd-emulator | 2 +- sw/bios/devices/sd_card.c | 2 + 4 files changed, 212 insertions(+), 209 deletions(-) diff --git a/hw/efinix_fpga/init_hex.mem b/hw/efinix_fpga/init_hex.mem index 8b65c22..febc8b5 100644 --- a/hw/efinix_fpga/init_hex.mem +++ b/hw/efinix_fpga/init_hex.mem @@ -1,9 +1,9 @@ @00000000 00 80 4C 00 00 8D 13 92 8E 14 92 8D 1A 92 8E 1B 92 88 B9 FF FF 8D 24 92 88 B9 FF FF 8D 23 92 8C -26 92 20 FF FF A0 FF D0 E8 60 00 00 A1 FD 00 00 -00 00 A2 FF 9A D8 A9 00 85 04 A9 DF 85 05 20 19 -FE 20 8E FA 20 52 F0 58 20 69 F2 6C FC FF 20 82 +26 92 20 FF FF A0 FF D0 E8 60 00 00 76 FD 00 00 +00 00 A2 FF 9A D8 A9 00 85 04 A9 DF 85 05 20 EE +FD 20 63 FA 20 52 F0 58 20 69 F2 6C FC FF 20 57 FA 00 A0 00 F0 07 A9 52 A2 F0 4C 05 92 60 AD FF EF A2 00 60 8D FF EF 60 20 4F F2 C9 0A D0 05 A9 0D 20 4F F2 60 DA 5A A8 B2 04 AA A9 1B 20 4F F2 @@ -13,19 +13,19 @@ A9 63 20 4F F2 68 60 40 DA BA 48 E8 E8 BD 00 01 29 10 D0 06 68 FA 20 68 F2 40 68 FA 7C BF F0 C5 F0 C9 F0 CA F0 20 9A F0 40 40 20 68 F0 40 48 A0 04 B1 04 09 40 20 3F F2 88 B1 04 20 3F F2 88 10 -F8 68 09 01 20 3F F2 20 7E FB 60 A2 08 A9 FF 20 +F8 68 09 01 20 3F F2 20 53 FB 60 A2 08 A9 FF 20 3F F2 C9 FF D0 03 CA D0 F4 60 85 0C 86 0D 20 EB -F0 92 0C A9 FF 20 3F F2 A0 01 91 0C 20 6B FB 60 -AA 20 F5 FC A9 FF 20 3F F2 92 0C E6 0C D0 02 E6 +F0 92 0C A9 FF 20 3F F2 A0 01 91 0C 20 40 FB 60 +AA 20 CA FC A9 FF 20 3F F2 92 0C E6 0C D0 02 E6 0D CA D0 F0 60 85 0C 86 0D 20 EB F0 C9 02 B0 12 -E6 0C D0 02 E6 0C A5 0C A6 0D 20 22 FD A9 04 20 +E6 0C D0 02 E6 0C A5 0C A6 0D 20 F7 FC A9 04 20 10 F1 60 48 A9 FF 20 3F F2 A9 00 20 33 F2 A9 FF 20 3F F2 68 20 CE F0 20 EB F0 A8 A9 FF 20 3F F2 A9 00 20 39 F2 A9 FF 20 3F F2 98 A2 00 60 A9 00 20 39 F2 20 8B F1 A9 FF 20 3F F2 A9 00 20 39 F2 A2 50 A9 FF 20 3F F2 CA D0 F8 60 A2 01 A9 C8 3A -D0 FD CA D0 F8 60 85 0E 86 0F A9 FF 92 0E 20 F5 -FC A5 04 85 10 A5 05 85 11 20 26 FB A0 00 B1 10 +D0 FD CA D0 F8 60 85 0E 86 0F A9 FF 92 0E 20 CA +FC A5 04 85 10 A5 05 85 11 20 FB FA A0 00 B1 10 91 04 C8 B1 10 91 04 C8 B1 10 91 04 C8 B1 10 91 04 A9 FF 20 3F F2 A9 00 20 33 F2 A9 FF 20 3F F2 A9 11 A0 04 91 04 A9 00 20 CE F0 20 EB F0 C9 FF @@ -37,207 +37,207 @@ EB A9 FF 20 3F F2 A9 FF 20 3F F2 A5 15 92 0E A5 F2 68 60 A9 01 8D DB EF 60 9C DB EF 60 A9 00 8D DA EF AD DB EF 30 FB AD D9 EF 60 8D E6 EF 60 48 8D E6 EF AD E7 EF 89 02 D0 F9 68 60 AD E6 EF A2 -00 60 AD E7 EF A2 00 60 60 20 49 FB A2 00 86 06 -86 07 A9 00 20 E0 FB 20 2F FB A9 5B A2 FE 20 EF -FA 20 3A F3 C9 00 20 8D FC D0 03 4C 98 F2 A9 54 -A2 FE 20 EF FA 4C 2E F3 A9 4B A2 FE 20 EF FA A0 -05 20 9C FB 20 E0 FB AD 00 92 AE 01 92 20 22 FD -A9 0C 20 AD FB 20 96 F1 A0 07 91 04 A0 07 A2 00 -B1 04 C9 00 20 93 FC D0 03 4C DC F2 A0 06 A2 00 -B1 04 C9 FE 20 93 FC F0 03 4C E5 F2 A2 00 A9 00 +00 60 AD E7 EF A2 00 60 60 20 1E FB A2 00 86 06 +86 07 A9 00 20 B5 FB 20 04 FB A9 30 A2 FE 20 C4 +FA 20 3A F3 C9 00 20 62 FC D0 03 4C 98 F2 A9 29 +A2 FE 20 C4 FA 4C 2E F3 A9 20 A2 FE 20 C4 FA A0 +05 20 71 FB 20 B5 FB AD 00 92 AE 01 92 20 F7 FC +A9 0C 20 82 FB 20 96 F1 A0 07 91 04 A0 07 A2 00 +B1 04 C9 00 20 68 FC D0 03 4C DC F2 A0 06 A2 00 +B1 04 C9 FE 20 68 FC F0 03 4C E5 F2 A2 00 A9 00 D0 03 4C E9 F2 A2 00 A9 01 D0 03 4C FA F2 AD 00 -92 AE 01 92 20 11 F6 4C 2B F3 A0 06 A2 00 B1 04 -A2 00 29 F0 20 74 FA D0 03 4C 16 F3 A9 54 A2 FE -20 EF FA 4C 2B F3 A9 3C A2 FE 20 22 FD A0 08 A2 -00 B1 04 20 22 FD A0 04 20 BB FA 6C 00 92 4C 31 -F3 4C 31 F3 A0 0C 20 5A FA 60 20 56 FB A9 00 20 -0C FD 20 6E F1 4C 71 F3 A0 00 A2 00 18 A9 01 71 -04 91 04 A0 00 A2 00 B1 04 C9 FF 20 93 FC D0 03 -4C 71 F3 A9 7A A2 FE 20 EF FA A2 00 A9 01 4C 7D -F4 20 81 F4 A0 01 91 04 C9 01 20 8D FC D0 C9 A9 -01 20 AD FB 20 9E F4 A0 01 A2 00 B1 04 C9 01 20 -8D FC D0 03 4C A5 F3 A9 71 A2 FE 20 EF FA A2 00 -A9 01 4C 7D F4 A0 05 A2 00 B1 04 C9 AA 20 8D FC -D0 03 4C BC F3 A2 00 A9 01 4C 7D F4 A2 00 A9 00 -A0 00 91 04 A0 00 A2 00 B1 04 C9 FF 20 93 FC D0 -03 4C E2 F3 A9 62 A2 FE 20 EF FA A2 00 A9 01 4C -7D F4 20 C0 F5 A0 01 91 04 A0 01 A2 00 B1 04 C9 -02 20 AC FC D0 03 4C 00 F4 20 DD F5 A0 01 91 04 -A2 00 A9 00 A0 06 20 3A FD A0 07 20 93 FB E0 03 -D0 02 C9 E8 20 AC FC F0 03 4C 1F F4 4C 2B F4 A0 -06 A2 00 A9 01 20 4A FA 4C 09 F4 A0 00 A2 00 18 -A9 01 71 04 91 04 A0 01 A2 00 B1 04 C9 00 20 8D -FC D0 81 A2 00 A9 00 A0 06 20 3A FD A0 07 20 93 -FB E0 03 D0 02 C9 E8 20 AC FC F0 03 4C 62 F4 4C -6E F4 A0 06 A2 00 A9 01 20 4A FA 4C 4C F4 A9 01 -20 AD FB 20 46 F5 A2 00 A9 00 4C 7D F4 20 83 FB -60 A2 00 A9 00 20 0C FD A2 00 86 06 86 07 A9 00 -20 E0 FB A2 00 A9 94 20 43 F1 4C 9D F4 60 20 22 -FD A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 A2 -00 A9 FF 20 3F F2 A2 00 A9 08 20 0C FD A2 01 A9 -00 85 06 A9 00 85 07 A9 AA 20 E0 FB A2 00 A9 86 -20 CE F0 A0 01 20 93 FB 20 25 F1 A2 00 A9 FF 20 -3F F2 A2 00 A9 00 20 39 F2 A2 00 A9 FF 20 3F F2 -20 6B FB 60 20 22 FD A2 00 A9 FF 20 3F F2 A2 00 -A9 00 20 33 F2 A2 00 A9 FF 20 3F F2 A2 00 A9 0D -20 0C FD A2 00 86 06 86 07 A9 00 20 E0 FB A2 00 -A9 00 20 CE F0 A0 01 20 93 FB 20 FA F0 A2 00 A9 -FF 20 3F F2 A2 00 A9 00 20 39 F2 A2 00 A9 FF 20 -3F F2 20 6B FB 60 20 22 FD 20 26 FB A2 00 A9 FF +92 AE 01 92 20 E6 F5 4C 2B F3 A0 06 A2 00 B1 04 +A2 00 29 F0 20 49 FA D0 03 4C 16 F3 A9 29 A2 FE +20 C4 FA 4C 2B F3 A9 11 A2 FE 20 F7 FC A0 08 A2 +00 B1 04 20 F7 FC A0 04 20 90 FA 6C 00 92 4C 31 +F3 4C 31 F3 A0 0C 20 2F FA 60 20 2B FB A9 00 20 +E1 FC 20 6E F1 4C 71 F3 A0 00 A2 00 18 A9 01 71 +04 91 04 A0 00 A2 00 B1 04 C9 FF 20 68 FC D0 03 +4C 71 F3 A9 4F A2 FE 20 C4 FA A2 00 A9 01 4C 52 +F4 20 56 F4 A0 01 91 04 C9 01 20 62 FC D0 C9 A9 +01 20 82 FB 20 73 F4 A0 01 A2 00 B1 04 C9 01 20 +62 FC D0 03 4C A5 F3 A9 46 A2 FE 20 C4 FA A2 00 +A9 01 4C 52 F4 A0 05 A2 00 B1 04 C9 AA 20 62 FC +D0 03 4C BC F3 A2 00 A9 01 4C 52 F4 A2 00 A9 00 +A0 00 91 04 A0 00 A2 00 B1 04 C9 FF 20 68 FC D0 +03 4C E2 F3 A9 37 A2 FE 20 C4 FA A2 00 A9 01 4C +52 F4 20 95 F5 A0 01 91 04 A0 01 A2 00 B1 04 C9 +02 20 81 FC D0 03 4C 00 F4 20 B2 F5 A0 01 91 04 +A0 00 A2 00 18 A9 01 71 04 91 04 A0 01 A2 00 B1 +04 C9 00 20 62 FC D0 AC A2 00 A9 00 A0 06 20 0F +FD A0 07 20 68 FB E0 03 D0 02 C9 E8 20 81 FC F0 +03 4C 37 F4 4C 43 F4 A0 06 A2 00 A9 01 20 1F FA +4C 21 F4 A9 01 20 82 FB 20 1B F5 A2 00 A9 00 4C +52 F4 20 58 FB 60 A2 00 A9 00 20 E1 FC A2 00 86 +06 86 07 A9 00 20 B5 FB A2 00 A9 94 20 43 F1 4C +72 F4 60 20 F7 FC A2 00 A9 FF 20 3F F2 A2 00 A9 +00 20 33 F2 A2 00 A9 FF 20 3F F2 A2 00 A9 08 20 +E1 FC A2 01 A9 00 85 06 A9 00 85 07 A9 AA 20 B5 +FB A2 00 A9 86 20 CE F0 A0 01 20 68 FB 20 25 F1 +A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 39 F2 A2 00 +A9 FF 20 3F F2 20 40 FB 60 20 F7 FC A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 A2 00 A9 FF 20 3F -F2 A0 00 91 04 A0 00 A2 00 B1 04 C9 FF 20 8D FC -D0 03 4C 86 F5 4C 78 F5 A2 00 A9 FF 20 3F F2 C9 -FF 20 8D FC D0 F2 A2 00 A9 3A 20 0C FD A2 00 86 -06 86 07 A9 00 20 E0 FB A2 00 A9 00 20 CE F0 A0 -02 20 93 FB 20 25 F1 A2 00 A9 FF 20 3F F2 A2 00 -A9 00 20 39 F2 A2 00 A9 FF 20 3F F2 20 79 FB 60 -A2 00 A9 37 20 0C FD A2 00 86 06 86 07 A9 00 20 -E0 FB A2 00 A9 00 20 43 F1 4C DC F5 60 A2 00 A9 -29 20 0C FD A2 00 86 06 A9 40 85 07 A9 00 20 E0 -FB A2 00 A9 00 20 43 F1 4C FB F5 60 20 22 FD 20 -49 FB A0 03 A2 00 B1 04 4C 0B F6 A0 0E 20 5A FA -60 20 22 FD A9 00 20 0C FD 20 2F FB A2 00 A9 00 -A0 00 20 3A FD A0 01 20 93 FB E0 02 20 AC FC F0 -03 4C 37 F6 4C 99 F6 A9 83 A2 FE 20 22 FD A0 06 -20 93 FB A0 00 20 88 FB 20 22 FD A0 07 A2 00 A9 -01 20 4A FA A0 04 20 BB FA A0 02 A2 00 B1 04 C9 -1F 20 93 FC D0 03 4C 7B F6 A9 87 A2 FE 20 EF FA -A2 00 A9 00 A0 02 91 04 4C 8D F6 A2 00 A9 20 20 -68 F0 A0 02 A2 00 18 A9 01 71 04 91 04 A0 00 A2 -00 A9 01 20 4A FA 4C 25 F6 A9 87 A2 FE 20 EF FA -20 7E FB 60 A0 00 B1 1A E6 1A D0 02 E6 1B 60 AD -4A 92 8D 45 92 20 50 F7 A9 45 A2 92 20 22 FD 20 -03 FD 4C 02 92 A5 18 38 E9 02 85 18 B0 02 C6 19 -60 AD 4F 92 D0 11 20 EE F6 4C 6D FA AD 4F 92 D0 -06 20 EE F6 4C 67 FA 20 EE F6 85 06 86 07 20 C5 -F6 A0 01 B1 18 AA 88 B1 18 60 A0 00 84 0C 84 0D -B1 1A 38 E9 30 90 2C C9 0A B0 28 20 A8 F6 48 A5 -0C A6 0D 06 0C 26 0D 06 0C 26 0D 65 0C 85 0C 8A -65 0D 85 0D 06 0C 26 0D 68 65 0C 85 0C 90 D1 E6 -0D B0 CD A5 0C A6 0D 60 AC 51 92 EE 51 92 99 52 -92 60 A9 52 A2 92 18 6D 51 92 90 01 E8 4C 22 FD -A5 1C A6 1D 4C 22 FD 20 AF F6 EE 4B 92 D0 F8 EE -4C 92 D0 F3 60 20 50 F7 AD 66 92 AE 67 92 20 22 -FD AD 68 92 AE 69 92 20 22 FD 4C 02 92 84 0C 20 -E0 FB 20 42 F7 A5 0C 4C 10 FC 84 0C 20 E0 FB 20 -42 F7 A5 0C 4C 51 FC 48 A0 05 B9 18 00 99 3F 92 -88 10 F7 68 85 18 86 19 20 63 FB 85 1A 86 1B 20 -63 FB 85 1C 86 1D A9 00 A8 91 1C C8 91 1C C8 B1 -1C 8D 03 92 C8 B1 1C 8D 04 92 A5 1A 85 0C A5 1B -85 0D A0 00 B1 1A F0 0B C9 25 F0 07 C8 D0 F5 E6 -1B D0 F1 98 18 65 1A 85 1A 90 02 E6 1B 38 E5 0C -85 0E A5 1B E5 0D 85 0F 05 0E F0 25 20 49 FB A0 -05 A5 1D 91 04 88 A5 1C 91 04 88 A5 0D 91 04 88 -A5 0C 91 04 88 A5 0F 91 04 88 A5 0E 91 04 20 02 -92 20 A4 F6 AA D0 0B A2 05 BD 3F 92 95 18 CA 10 -F8 60 C9 25 D0 09 B1 1A C9 25 D0 09 20 A8 F6 20 -B2 F6 4C CA F7 A9 00 A2 0B 9D 46 92 CA 10 FA B1 -1A C9 2D D0 05 8E 46 92 F0 19 C9 2B D0 05 8E 47 -92 F0 10 C9 20 D0 05 8E 48 92 F0 07 C9 23 D0 09 -8E 49 92 20 A8 F6 4C 4F F8 A2 20 C9 30 D0 06 AA -20 A8 F6 B1 1A 8E 4A 92 C9 2A D0 09 20 A8 F6 20 -EE F6 4C 98 F8 20 FA F6 8D 4B 92 8E 4C 92 8C 4D -92 8C 4E 92 B1 1A C9 2E D0 1B 20 A8 F6 B1 1A C9 -2A D0 09 20 A8 F6 20 EE F6 4C BF F8 20 FA F6 8D -4D 92 8E 4E 92 B1 1A C9 7A F0 19 C9 68 F0 15 C9 -74 F0 11 C9 6A F0 08 C9 4C F0 04 C9 6C D0 0B A9 -FF 8D 4F 92 20 A8 F6 4C C5 F8 8C 51 92 A2 52 8E -66 92 A2 92 8E 67 92 20 A8 F6 C9 63 D0 0D 20 EE -F6 8D 52 92 A2 00 A9 01 4C F1 F9 C9 64 F0 04 C9 -69 D0 2D A2 00 AD 48 92 F0 02 A2 20 AD 47 92 F0 -02 A2 2B 8E 50 92 20 DC F6 A4 07 30 0B AC 50 92 -F0 06 8C 52 92 EE 51 92 A0 0A 20 7D F7 4C E8 F9 -C9 6E D0 15 20 EE F6 85 0C 86 0D A0 00 B1 1C 91 -0C C8 B1 1C 91 0C 4C CA F7 C9 6F D0 27 20 DC F6 -AC 49 92 F0 17 48 86 14 05 14 05 06 05 07 0D 4D -92 0D 4E 92 F0 06 A9 30 20 38 F7 68 A0 08 20 7D -F7 4C E8 F9 C9 70 D0 0D A2 00 8E 4F 92 E8 8E 49 -92 A9 78 D0 27 C9 73 D0 0C 20 EE F6 8D 66 92 8E -67 92 4C E8 F9 C9 75 D0 0B 20 D1 F6 A0 0A 20 8A -F7 4C E8 F9 C9 78 F0 04 C9 58 D0 29 48 AD 49 92 -F0 0A A9 30 20 38 F7 A9 58 20 38 F7 20 D1 F6 A0 -10 20 8A F7 68 C9 78 D0 09 AD 66 92 AE 67 92 20 -7A FD 4C E8 F9 4C CA F7 AD 66 92 AE 67 92 20 64 -FD 8D 68 92 8E 69 92 AD 4D 92 0D 4E 92 F0 15 AE -4D 92 EC 68 92 AD 4E 92 A8 ED 69 92 B0 06 8E 68 -92 8C 69 92 38 AD 4B 92 ED 68 92 AA AD 4C 92 ED -69 92 B0 03 A9 00 AA 49 FF 8D 4C 92 8A 49 FF 8D -4B 92 AD 46 92 D0 03 20 5A F7 20 65 F7 AD 46 92 -F0 03 20 5A F7 4C CA F7 A0 00 18 71 04 91 04 48 -C8 8A 71 04 91 04 AA 68 60 C8 48 18 98 65 04 85 -04 90 02 E6 05 68 60 A0 FF E0 80 B0 02 A0 00 84 -06 84 07 60 E0 00 D0 06 AA D0 03 A9 01 60 A2 00 -8A 60 A0 00 F0 07 A9 52 A2 F0 4C 05 92 60 A9 00 -85 0C A9 F0 85 0D A9 00 85 0E A9 92 85 0F A2 CD -A9 FF 85 14 A0 00 E8 F0 0D B1 0C 91 0E C8 D0 F6 -E6 0D E6 0F D0 F0 E6 14 D0 EF 60 8C 6A 92 88 88 -98 18 65 04 85 0C A6 05 90 01 E8 86 0D A0 01 B1 -0C AA 88 B1 0C 20 22 FD A5 0C A6 0D 20 E9 FD AC -6A 92 4C 5A FA 85 0C 86 0D 20 75 F0 4C F3 FA 85 -0C 86 0D A0 00 B1 0C F0 0E C8 84 14 20 68 F0 A4 -14 D0 F2 E6 0D D0 EE 60 E0 00 D0 15 4A AA BD B0 -FE 90 05 4A 4A 4A 4A 18 29 0F AA BD A5 FE A2 00 -60 38 A9 00 AA 60 A4 04 D0 02 C6 05 C6 04 60 A5 -04 38 E9 02 85 04 90 01 60 C6 05 60 A5 04 38 E9 -04 85 04 90 01 60 C6 05 60 A5 04 38 E9 06 85 04 -90 01 60 C6 05 60 A5 04 38 E9 07 85 04 90 01 60 -C6 05 60 A0 01 B1 04 AA 88 B1 04 E6 04 F0 05 E6 -04 F0 03 60 E6 04 E6 05 60 A0 03 4C 5A FA A0 05 -4C 5A FA A0 08 4C 5A FA 85 0C 86 0D A2 00 B1 0C -60 A0 01 B1 04 AA 88 B1 04 60 A0 03 B1 04 85 07 -88 B1 04 85 06 88 B1 04 AA 88 B1 04 60 A2 00 18 -65 04 48 8A 65 05 AA 68 60 18 49 FF 69 01 48 8A -49 FF 69 00 AA A5 06 49 FF 69 00 85 06 A5 07 49 -FF 69 00 85 07 68 60 A9 00 AA A0 00 84 06 84 07 -48 20 3C FB A0 03 A5 07 91 04 88 A5 06 91 04 88 -8A 91 04 68 88 91 04 60 85 14 20 63 FB 85 0E 86 -0F 85 10 86 11 20 F5 FC 20 63 FB 85 06 86 07 60 -20 F8 FB A6 07 A4 14 C0 0A D0 39 A5 06 05 0D 05 -0C D0 11 E0 80 D0 0D A0 0B B9 99 FE 91 0E 88 10 -F8 4C 88 FC 8A 10 1D A9 2D A0 00 91 0E E6 0E D0 -02 E6 0F A5 0C A6 0D 20 B9 FB 85 0C 86 0D 4C 54 -FC 20 F8 FB A9 00 48 A0 20 A9 00 06 0C 26 0D 26 -06 26 07 2A C5 14 90 04 E5 14 E6 0C 88 D0 EC A8 -B9 89 FE 48 A5 0C 05 0D 05 06 05 07 D0 D9 A0 00 -68 91 0E F0 03 C8 D0 F8 A5 10 A6 11 60 D0 06 A2 -00 8A 60 D0 FA A2 00 A9 01 60 F0 F9 30 F7 A2 00 -8A 60 F0 02 10 EF A2 00 8A 60 F0 E9 90 E7 A2 00 -8A 60 F0 DB A2 00 8A 2A 60 20 E2 FC A6 11 F0 13 -B1 0C 91 0E C8 B1 0C 91 0E C8 D0 F4 E6 0D E6 0F -CA D0 ED A6 10 F0 08 B1 0C 91 0E C8 CA D0 F8 4C -63 FB 85 10 86 11 20 F5 FC C8 B1 04 AA 86 0F 88 -B1 04 85 0E 60 A0 01 B1 04 85 0D 88 B1 04 85 0C -4C 6B FB A9 01 4C 20 FD A0 00 B1 04 A4 04 F0 07 -C6 04 A0 00 91 04 60 C6 05 C6 04 91 04 60 A9 00 -A2 00 48 A5 04 38 E9 02 85 04 B0 02 C6 05 A0 01 -8A 91 04 68 88 91 04 60 A0 00 91 04 C8 48 8A 91 -04 68 60 85 0E 86 0F 20 F5 FC B1 0C D1 0E D0 0C -AA F0 10 C8 D0 F4 E6 0D E6 0F D0 EE B0 03 A2 FF -60 A2 01 60 85 0E 86 0F A2 00 A0 00 B1 0E F0 08 -C8 D0 F9 E6 0F E8 D0 F4 98 60 85 0C 86 0D 85 0E -86 0F A0 00 B1 0C F0 14 20 0C FB 29 02 F0 06 B1 -0C 69 20 91 0C C8 D0 EC E6 0D D0 E8 A5 0E A6 0F -60 20 63 FB 85 0E 86 0F E8 8E 31 92 AA E8 8E 30 -92 20 F5 FC 20 63 FB 85 10 86 11 A0 00 84 14 B1 -10 18 65 0E 91 10 C8 B1 10 65 0F 91 10 CE 30 92 -F0 11 A4 14 B1 0C C8 D0 02 E6 0D 84 14 20 68 F0 -4C CD FD CE 31 92 D0 EA 60 85 0C 86 0D A9 00 8D -2A 92 8D 2B 92 A0 01 B1 04 AA 88 B1 04 20 22 FD -A0 02 A9 2A 91 04 C8 A9 92 91 04 A5 0C A6 0D 20 -97 F7 AD 2A 92 AE 2B 92 60 A9 32 85 0C A9 92 85 -0D A9 00 A8 A2 00 F0 0A 91 0C C8 D0 FB E6 0D CA -D0 F6 C0 39 F0 05 91 0C C8 D0 F7 60 62 61 64 20 -74 6F 6B 65 6E 3A 20 25 78 0A 00 53 75 63 63 65 -73 73 0A 00 45 72 72 6F 72 0A 00 53 74 61 72 74 -0A 00 6F 70 5F 63 6F 6E 64 20 65 72 72 6F 72 0A -00 49 46 20 43 6F 6E 64 0A 00 47 6F 20 49 44 4C -45 0A 00 25 32 78 00 0A 00 30 31 32 33 34 35 36 -37 38 39 41 42 43 44 45 46 2D 32 31 34 37 34 38 -33 36 34 38 00 00 01 02 0C 09 0A 10 40 50 A0 D0 -66 66 66 66 A6 88 88 66 66 66 66 66 66 66 66 66 -09 00 00 00 00 00 00 00 33 33 33 33 33 00 00 00 -50 55 55 25 22 22 22 22 22 22 22 22 22 02 00 00 -40 44 44 14 11 11 11 11 11 11 11 11 11 01 00 70 +F2 A2 00 A9 0D 20 E1 FC A2 00 86 06 86 07 A9 00 +20 B5 FB A2 00 A9 00 20 CE F0 A0 01 20 68 FB 20 +FA F0 A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 39 F2 +A2 00 A9 FF 20 3F F2 20 40 FB 60 20 F7 FC 20 FB +FA A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 A2 +00 A9 FF 20 3F F2 A0 00 91 04 A0 00 A2 00 B1 04 +C9 FF 20 62 FC D0 03 4C 5B F5 4C 4D F5 A2 00 A9 +FF 20 3F F2 C9 FF 20 62 FC D0 F2 A2 00 A9 3A 20 +E1 FC A2 00 86 06 86 07 A9 00 20 B5 FB A2 00 A9 +00 20 CE F0 A0 02 20 68 FB 20 25 F1 A2 00 A9 FF +20 3F F2 A2 00 A9 00 20 39 F2 A2 00 A9 FF 20 3F +F2 20 4E FB 60 A2 00 A9 37 20 E1 FC A2 00 86 06 +86 07 A9 00 20 B5 FB A2 00 A9 00 20 43 F1 4C B1 +F5 60 A2 00 A9 29 20 E1 FC A2 00 86 06 A9 40 85 +07 A9 00 20 B5 FB A2 00 A9 00 20 43 F1 4C D0 F5 +60 20 F7 FC 20 1E FB A0 03 A2 00 B1 04 4C E0 F5 +A0 0E 20 2F FA 60 20 F7 FC A9 00 20 E1 FC 20 04 +FB A2 00 A9 00 A0 00 20 0F FD A0 01 20 68 FB E0 +02 20 81 FC F0 03 4C 0C F6 4C 6E F6 A9 58 A2 FE +20 F7 FC A0 06 20 68 FB A0 00 20 5D FB 20 F7 FC +A0 07 A2 00 A9 01 20 1F FA A0 04 20 90 FA A0 02 +A2 00 B1 04 C9 1F 20 68 FC D0 03 4C 50 F6 A9 5C +A2 FE 20 C4 FA A2 00 A9 00 A0 02 91 04 4C 62 F6 +A2 00 A9 20 20 68 F0 A0 02 A2 00 18 A9 01 71 04 +91 04 A0 00 A2 00 A9 01 20 1F FA 4C FA F5 A9 5C +A2 FE 20 C4 FA 20 53 FB 60 A0 00 B1 1A E6 1A D0 +02 E6 1B 60 AD 4A 92 8D 45 92 20 25 F7 A9 45 A2 +92 20 F7 FC 20 D8 FC 4C 02 92 A5 18 38 E9 02 85 +18 B0 02 C6 19 60 AD 4F 92 D0 11 20 C3 F6 4C 42 +FA AD 4F 92 D0 06 20 C3 F6 4C 3C FA 20 C3 F6 85 +06 86 07 20 9A F6 A0 01 B1 18 AA 88 B1 18 60 A0 +00 84 0C 84 0D B1 1A 38 E9 30 90 2C C9 0A B0 28 +20 7D F6 48 A5 0C A6 0D 06 0C 26 0D 06 0C 26 0D +65 0C 85 0C 8A 65 0D 85 0D 06 0C 26 0D 68 65 0C +85 0C 90 D1 E6 0D B0 CD A5 0C A6 0D 60 AC 51 92 +EE 51 92 99 52 92 60 A9 52 A2 92 18 6D 51 92 90 +01 E8 4C F7 FC A5 1C A6 1D 4C F7 FC 20 84 F6 EE +4B 92 D0 F8 EE 4C 92 D0 F3 60 20 25 F7 AD 66 92 +AE 67 92 20 F7 FC AD 68 92 AE 69 92 20 F7 FC 4C +02 92 84 0C 20 B5 FB 20 17 F7 A5 0C 4C E5 FB 84 +0C 20 B5 FB 20 17 F7 A5 0C 4C 26 FC 48 A0 05 B9 +18 00 99 3F 92 88 10 F7 68 85 18 86 19 20 38 FB +85 1A 86 1B 20 38 FB 85 1C 86 1D A9 00 A8 91 1C +C8 91 1C C8 B1 1C 8D 03 92 C8 B1 1C 8D 04 92 A5 +1A 85 0C A5 1B 85 0D A0 00 B1 1A F0 0B C9 25 F0 +07 C8 D0 F5 E6 1B D0 F1 98 18 65 1A 85 1A 90 02 +E6 1B 38 E5 0C 85 0E A5 1B E5 0D 85 0F 05 0E F0 +25 20 1E FB A0 05 A5 1D 91 04 88 A5 1C 91 04 88 +A5 0D 91 04 88 A5 0C 91 04 88 A5 0F 91 04 88 A5 +0E 91 04 20 02 92 20 79 F6 AA D0 0B A2 05 BD 3F +92 95 18 CA 10 F8 60 C9 25 D0 09 B1 1A C9 25 D0 +09 20 7D F6 20 87 F6 4C 9F F7 A9 00 A2 0B 9D 46 +92 CA 10 FA B1 1A C9 2D D0 05 8E 46 92 F0 19 C9 +2B D0 05 8E 47 92 F0 10 C9 20 D0 05 8E 48 92 F0 +07 C9 23 D0 09 8E 49 92 20 7D F6 4C 24 F8 A2 20 +C9 30 D0 06 AA 20 7D F6 B1 1A 8E 4A 92 C9 2A D0 +09 20 7D F6 20 C3 F6 4C 6D F8 20 CF F6 8D 4B 92 +8E 4C 92 8C 4D 92 8C 4E 92 B1 1A C9 2E D0 1B 20 +7D F6 B1 1A C9 2A D0 09 20 7D F6 20 C3 F6 4C 94 +F8 20 CF F6 8D 4D 92 8E 4E 92 B1 1A C9 7A F0 19 +C9 68 F0 15 C9 74 F0 11 C9 6A F0 08 C9 4C F0 04 +C9 6C D0 0B A9 FF 8D 4F 92 20 7D F6 4C 9A F8 8C +51 92 A2 52 8E 66 92 A2 92 8E 67 92 20 7D F6 C9 +63 D0 0D 20 C3 F6 8D 52 92 A2 00 A9 01 4C C6 F9 +C9 64 F0 04 C9 69 D0 2D A2 00 AD 48 92 F0 02 A2 +20 AD 47 92 F0 02 A2 2B 8E 50 92 20 B1 F6 A4 07 +30 0B AC 50 92 F0 06 8C 52 92 EE 51 92 A0 0A 20 +52 F7 4C BD F9 C9 6E D0 15 20 C3 F6 85 0C 86 0D +A0 00 B1 1C 91 0C C8 B1 1C 91 0C 4C 9F F7 C9 6F +D0 27 20 B1 F6 AC 49 92 F0 17 48 86 14 05 14 05 +06 05 07 0D 4D 92 0D 4E 92 F0 06 A9 30 20 0D F7 +68 A0 08 20 52 F7 4C BD F9 C9 70 D0 0D A2 00 8E +4F 92 E8 8E 49 92 A9 78 D0 27 C9 73 D0 0C 20 C3 +F6 8D 66 92 8E 67 92 4C BD F9 C9 75 D0 0B 20 A6 +F6 A0 0A 20 5F F7 4C BD F9 C9 78 F0 04 C9 58 D0 +29 48 AD 49 92 F0 0A A9 30 20 0D F7 A9 58 20 0D +F7 20 A6 F6 A0 10 20 5F F7 68 C9 78 D0 09 AD 66 +92 AE 67 92 20 4F FD 4C BD F9 4C 9F F7 AD 66 92 +AE 67 92 20 39 FD 8D 68 92 8E 69 92 AD 4D 92 0D +4E 92 F0 15 AE 4D 92 EC 68 92 AD 4E 92 A8 ED 69 +92 B0 06 8E 68 92 8C 69 92 38 AD 4B 92 ED 68 92 +AA AD 4C 92 ED 69 92 B0 03 A9 00 AA 49 FF 8D 4C +92 8A 49 FF 8D 4B 92 AD 46 92 D0 03 20 2F F7 20 +3A F7 AD 46 92 F0 03 20 2F F7 4C 9F F7 A0 00 18 +71 04 91 04 48 C8 8A 71 04 91 04 AA 68 60 C8 48 +18 98 65 04 85 04 90 02 E6 05 68 60 A0 FF E0 80 +B0 02 A0 00 84 06 84 07 60 E0 00 D0 06 AA D0 03 +A9 01 60 A2 00 8A 60 A0 00 F0 07 A9 52 A2 F0 4C +05 92 60 A9 00 85 0C A9 F0 85 0D A9 00 85 0E A9 +92 85 0F A2 CD A9 FF 85 14 A0 00 E8 F0 0D B1 0C +91 0E C8 D0 F6 E6 0D E6 0F D0 F0 E6 14 D0 EF 60 +8C 6A 92 88 88 98 18 65 04 85 0C A6 05 90 01 E8 +86 0D A0 01 B1 0C AA 88 B1 0C 20 F7 FC A5 0C A6 +0D 20 BE FD AC 6A 92 4C 2F FA 85 0C 86 0D 20 75 +F0 4C C8 FA 85 0C 86 0D A0 00 B1 0C F0 0E C8 84 +14 20 68 F0 A4 14 D0 F2 E6 0D D0 EE 60 E0 00 D0 +15 4A AA BD 85 FE 90 05 4A 4A 4A 4A 18 29 0F AA +BD 7A FE A2 00 60 38 A9 00 AA 60 A4 04 D0 02 C6 +05 C6 04 60 A5 04 38 E9 02 85 04 90 01 60 C6 05 +60 A5 04 38 E9 04 85 04 90 01 60 C6 05 60 A5 04 +38 E9 06 85 04 90 01 60 C6 05 60 A5 04 38 E9 07 +85 04 90 01 60 C6 05 60 A0 01 B1 04 AA 88 B1 04 +E6 04 F0 05 E6 04 F0 03 60 E6 04 E6 05 60 A0 03 +4C 2F FA A0 05 4C 2F FA A0 08 4C 2F FA 85 0C 86 +0D A2 00 B1 0C 60 A0 01 B1 04 AA 88 B1 04 60 A0 +03 B1 04 85 07 88 B1 04 85 06 88 B1 04 AA 88 B1 +04 60 A2 00 18 65 04 48 8A 65 05 AA 68 60 18 49 +FF 69 01 48 8A 49 FF 69 00 AA A5 06 49 FF 69 00 +85 06 A5 07 49 FF 69 00 85 07 68 60 A9 00 AA A0 +00 84 06 84 07 48 20 11 FB A0 03 A5 07 91 04 88 +A5 06 91 04 88 8A 91 04 68 88 91 04 60 85 14 20 +38 FB 85 0E 86 0F 85 10 86 11 20 CA FC 20 38 FB +85 06 86 07 60 20 CD FB A6 07 A4 14 C0 0A D0 39 +A5 06 05 0D 05 0C D0 11 E0 80 D0 0D A0 0B B9 6E +FE 91 0E 88 10 F8 4C 5D FC 8A 10 1D A9 2D A0 00 +91 0E E6 0E D0 02 E6 0F A5 0C A6 0D 20 8E FB 85 +0C 86 0D 4C 29 FC 20 CD FB A9 00 48 A0 20 A9 00 +06 0C 26 0D 26 06 26 07 2A C5 14 90 04 E5 14 E6 +0C 88 D0 EC A8 B9 5E FE 48 A5 0C 05 0D 05 06 05 +07 D0 D9 A0 00 68 91 0E F0 03 C8 D0 F8 A5 10 A6 +11 60 D0 06 A2 00 8A 60 D0 FA A2 00 A9 01 60 F0 +F9 30 F7 A2 00 8A 60 F0 02 10 EF A2 00 8A 60 F0 +E9 90 E7 A2 00 8A 60 F0 DB A2 00 8A 2A 60 20 B7 +FC A6 11 F0 13 B1 0C 91 0E C8 B1 0C 91 0E C8 D0 +F4 E6 0D E6 0F CA D0 ED A6 10 F0 08 B1 0C 91 0E +C8 CA D0 F8 4C 38 FB 85 10 86 11 20 CA FC C8 B1 +04 AA 86 0F 88 B1 04 85 0E 60 A0 01 B1 04 85 0D +88 B1 04 85 0C 4C 40 FB A9 01 4C F5 FC A0 00 B1 +04 A4 04 F0 07 C6 04 A0 00 91 04 60 C6 05 C6 04 +91 04 60 A9 00 A2 00 48 A5 04 38 E9 02 85 04 B0 +02 C6 05 A0 01 8A 91 04 68 88 91 04 60 A0 00 91 +04 C8 48 8A 91 04 68 60 85 0E 86 0F 20 CA FC B1 +0C D1 0E D0 0C AA F0 10 C8 D0 F4 E6 0D E6 0F D0 +EE B0 03 A2 FF 60 A2 01 60 85 0E 86 0F A2 00 A0 +00 B1 0E F0 08 C8 D0 F9 E6 0F E8 D0 F4 98 60 85 +0C 86 0D 85 0E 86 0F A0 00 B1 0C F0 14 20 E1 FA +29 02 F0 06 B1 0C 69 20 91 0C C8 D0 EC E6 0D D0 +E8 A5 0E A6 0F 60 20 38 FB 85 0E 86 0F E8 8E 31 +92 AA E8 8E 30 92 20 CA FC 20 38 FB 85 10 86 11 +A0 00 84 14 B1 10 18 65 0E 91 10 C8 B1 10 65 0F +91 10 CE 30 92 F0 11 A4 14 B1 0C C8 D0 02 E6 0D +84 14 20 68 F0 4C A2 FD CE 31 92 D0 EA 60 85 0C +86 0D A9 00 8D 2A 92 8D 2B 92 A0 01 B1 04 AA 88 +B1 04 20 F7 FC A0 02 A9 2A 91 04 C8 A9 92 91 04 +A5 0C A6 0D 20 6C F7 AD 2A 92 AE 2B 92 60 A9 32 +85 0C A9 92 85 0D A9 00 A8 A2 00 F0 0A 91 0C C8 +D0 FB E6 0D CA D0 F6 C0 39 F0 05 91 0C C8 D0 F7 +60 62 61 64 20 74 6F 6B 65 6E 3A 20 25 78 0A 00 +53 75 63 63 65 73 73 0A 00 45 72 72 6F 72 0A 00 +53 74 61 72 74 0A 00 6F 70 5F 63 6F 6E 64 20 65 +72 72 6F 72 0A 00 49 46 20 43 6F 6E 64 0A 00 47 +6F 20 49 44 4C 45 0A 00 25 32 78 00 0A 00 30 31 +32 33 34 35 36 37 38 39 41 42 43 44 45 46 2D 32 +31 34 37 34 38 33 36 34 38 00 00 01 02 0C 09 0A +10 40 50 A0 D0 66 66 66 66 A6 88 88 66 66 66 66 +66 66 66 66 66 09 00 00 00 00 00 00 00 33 33 33 +33 33 00 00 00 50 55 55 25 22 22 22 22 22 22 22 +22 22 02 00 00 40 44 44 14 11 11 11 11 11 11 11 +11 11 01 00 70 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index f5cafb0..2bd143a 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -88,6 +88,7 @@ logic w_spi_mosi; logic w_spi_miso; sd_card_emu u_sd_card_emu( + .rst(~w_cpu_reset), .clk(w_spi_clk), .cs(w_sd_cs), .mosi(w_spi_mosi), diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 27a4e5d..2ae36c9 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 27a4e5dd87e61ef84f13ea614d0b4ed3293c85c0 +Subproject commit 2ae36c9dcd99c02b864709134d931c431603f9a0 diff --git a/sw/bios/devices/sd_card.c b/sw/bios/devices/sd_card.c index 404bb7a..0387b50 100644 --- a/sw/bios/devices/sd_card.c +++ b/sw/bios/devices/sd_card.c @@ -56,7 +56,9 @@ uint8_t SD_init() res[0] = SD_sendOpCond(); } +#ifndef RTL_SIM for (i = 0; i < 1000; i++); +#endif cmdAttempts++; } From 6a684f62f8e03e7657eb780edc055b75f56032b2 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 4 Oct 2023 20:24:56 -0700 Subject: [PATCH 34/57] Remove another wait, update sd emulator --- hw/efinix_fpga/simulation/src/verilog-sd-emulator | 2 +- sw/bios/devices/sd_card.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 2ae36c9..016ca4b 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 2ae36c9dcd99c02b864709134d931c431603f9a0 +Subproject commit 016ca4bce23a3c9772e466279c6e1a2440af72b0 diff --git a/sw/bios/devices/sd_card.c b/sw/bios/devices/sd_card.c index 0387b50..6be2cc3 100644 --- a/sw/bios/devices/sd_card.c +++ b/sw/bios/devices/sd_card.c @@ -64,7 +64,9 @@ uint8_t SD_init() } while(res[0] != SD_READY); +#ifndef RTL_SIM for (i = 0; i < 1000; i++); +#endif SD_readOCR(res); From e6e3044f25b87969aeb007b54b514d54a4617b34 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 4 Oct 2023 20:27:25 -0700 Subject: [PATCH 35/57] update sd emulator --- hw/efinix_fpga/simulation/src/verilog-sd-emulator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 016ca4b..1c66557 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 016ca4bce23a3c9772e466279c6e1a2440af72b0 +Subproject commit 1c66557642a27ad2989c5f2321dd22a6bb7d6855 From 2b98ad15228fbc9baad788481fbd11299c23161a Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 4 Oct 2023 22:50:55 -0700 Subject: [PATCH 36/57] Increase sim time to get into sd block reads --- hw/efinix_fpga/simulation/src/sim_top.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 2bd143a..f61e015 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -49,7 +49,7 @@ initial begin button_reset <= '0; repeat(10) @(r_clk_2); button_reset <= '1; - repeat(50000) @(r_clk_2); + repeat(150000) @(r_clk_2); $finish(); end From 2084054d3d60c2e02ac24d708ad88bb4630c9e1a Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Fri, 6 Oct 2023 06:48:47 -0700 Subject: [PATCH 37/57] Add script for creating verilog filesystem image --- sw/.gitignore | 3 +++ sw/script/create_verilog_image.sh | 42 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 sw/script/create_verilog_image.sh diff --git a/sw/.gitignore b/sw/.gitignore index ec73f2b..5e3b75b 100644 --- a/sw/.gitignore +++ b/sw/.gitignore @@ -53,3 +53,6 @@ modules.order Module.symvers Mkfile.old dkms.conf + +# Filesystem Images +*.fat diff --git a/sw/script/create_verilog_image.sh b/sw/script/create_verilog_image.sh new file mode 100644 index 0000000..e95ce0b --- /dev/null +++ b/sw/script/create_verilog_image.sh @@ -0,0 +1,42 @@ + +#!/bin/bash + +BOOTLOADER=../bios/bootloader.bin +FILE=fs.fat + +TMPMOUNT=/tmp/lo +FSDIR=../fsdir + +V=-v + +# Smallest number of blocks where mkfs doesn't complain +BLOCKS=33296 + +rm $FILE + +echo "$(tput bold setaf 11)Creating Filesystem$(tput sgr 0)" +mkfs.vfat $V -I -F32 -C $FILE -n SUPER6502 $BLOCKS +echo + +echo "$(tput bold setaf 11)Modifying Boot Sector$(tput sgr 0)" +dd if=$BOOTLOADER of=$FILE bs=1 conv=notrunc count=11 $STATUS +dd if=$BOOTLOADER of=$FILE bs=1 conv=notrunc count=380 seek=71 skip=71 $STATUS + +echo "$(tput bold setaf 11)Mounting Device$(tput sgr 0)" +mkdir $V -p $TMPMOUNT +sudo mount $FILE $TMPMOUNT +echo + +echo "$(tput bold setaf 11)Copying Files$(tput sgr 0)" +sudo cp $V -r $FSDIR/* $TMPMOUNT +echo + +echo "$(tput bold setaf 11)Unmounting Device$(tput sgr 0)" +sudo umount $V $FILE +rmdir $V $TMPMOUNT +echo + +echo "$(tput bold setaf 11)Converting Image to Verilog$(tput sgr 0)" +objcopy --input-target=binary --output-target=verilog $FILE $FILE.hex +echo "$(tput bold setaf 10)Done!$(tput sgr 0)" + From a3e0ab0e1e87203b4d750398ce14d90a4af4cceb Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Fri, 6 Oct 2023 07:23:36 -0700 Subject: [PATCH 38/57] Use 8 bit memory !! Will eat all your RAM! Figure out a better way to load memories that doesn't immediately oom you. --- hw/efinix_fpga/init_hex.mem | 412 +++++++++--------- hw/efinix_fpga/simulation/Makefile | 9 +- hw/efinix_fpga/simulation/src/sim_top.sv | 4 +- .../simulation/src/verilog-sd-emulator | 2 +- sw/script/create_verilog_image.sh | 4 +- 5 files changed, 219 insertions(+), 212 deletions(-) diff --git a/hw/efinix_fpga/init_hex.mem b/hw/efinix_fpga/init_hex.mem index febc8b5..2b05a54 100644 --- a/hw/efinix_fpga/init_hex.mem +++ b/hw/efinix_fpga/init_hex.mem @@ -1,9 +1,9 @@ @00000000 00 80 4C 00 00 8D 13 92 8E 14 92 8D 1A 92 8E 1B 92 88 B9 FF FF 8D 24 92 88 B9 FF FF 8D 23 92 8C -26 92 20 FF FF A0 FF D0 E8 60 00 00 76 FD 00 00 -00 00 A2 FF 9A D8 A9 00 85 04 A9 DF 85 05 20 EE -FD 20 63 FA 20 52 F0 58 20 69 F2 6C FC FF 20 57 +26 92 20 FF FF A0 FF D0 E8 60 00 00 4C FD 00 00 +00 00 A2 FF 9A D8 A9 00 85 04 A9 DF 85 05 20 C4 +FD 20 39 FA 20 52 F0 58 20 69 F2 6C FC FF 20 2D FA 00 A0 00 F0 07 A9 52 A2 F0 4C 05 92 60 AD FF EF A2 00 60 8D FF EF 60 20 4F F2 C9 0A D0 05 A9 0D 20 4F F2 60 DA 5A A8 B2 04 AA A9 1B 20 4F F2 @@ -13,19 +13,19 @@ A9 63 20 4F F2 68 60 40 DA BA 48 E8 E8 BD 00 01 29 10 D0 06 68 FA 20 68 F2 40 68 FA 7C BF F0 C5 F0 C9 F0 CA F0 20 9A F0 40 40 20 68 F0 40 48 A0 04 B1 04 09 40 20 3F F2 88 B1 04 20 3F F2 88 10 -F8 68 09 01 20 3F F2 20 53 FB 60 A2 08 A9 FF 20 +F8 68 09 01 20 3F F2 20 29 FB 60 A2 08 A9 FF 20 3F F2 C9 FF D0 03 CA D0 F4 60 85 0C 86 0D 20 EB -F0 92 0C A9 FF 20 3F F2 A0 01 91 0C 20 40 FB 60 -AA 20 CA FC A9 FF 20 3F F2 92 0C E6 0C D0 02 E6 +F0 92 0C A9 FF 20 3F F2 A0 01 91 0C 20 16 FB 60 +AA 20 A0 FC A9 FF 20 3F F2 92 0C E6 0C D0 02 E6 0D CA D0 F0 60 85 0C 86 0D 20 EB F0 C9 02 B0 12 -E6 0C D0 02 E6 0C A5 0C A6 0D 20 F7 FC A9 04 20 +E6 0C D0 02 E6 0C A5 0C A6 0D 20 CD FC A9 04 20 10 F1 60 48 A9 FF 20 3F F2 A9 00 20 33 F2 A9 FF 20 3F F2 68 20 CE F0 20 EB F0 A8 A9 FF 20 3F F2 A9 00 20 39 F2 A9 FF 20 3F F2 98 A2 00 60 A9 00 20 39 F2 20 8B F1 A9 FF 20 3F F2 A9 00 20 39 F2 A2 50 A9 FF 20 3F F2 CA D0 F8 60 A2 01 A9 C8 3A -D0 FD CA D0 F8 60 85 0E 86 0F A9 FF 92 0E 20 CA -FC A5 04 85 10 A5 05 85 11 20 FB FA A0 00 B1 10 +D0 FD CA D0 F8 60 85 0E 86 0F A9 FF 92 0E 20 A0 +FC A5 04 85 10 A5 05 85 11 20 D1 FA A0 00 B1 10 91 04 C8 B1 10 91 04 C8 B1 10 91 04 C8 B1 10 91 04 A9 FF 20 3F F2 A9 00 20 33 F2 A9 FF 20 3F F2 A9 11 A0 04 91 04 A9 00 20 CE F0 20 EB F0 C9 FF @@ -37,205 +37,205 @@ EB A9 FF 20 3F F2 A9 FF 20 3F F2 A5 15 92 0E A5 F2 68 60 A9 01 8D DB EF 60 9C DB EF 60 A9 00 8D DA EF AD DB EF 30 FB AD D9 EF 60 8D E6 EF 60 48 8D E6 EF AD E7 EF 89 02 D0 F9 68 60 AD E6 EF A2 -00 60 AD E7 EF A2 00 60 60 20 1E FB A2 00 86 06 -86 07 A9 00 20 B5 FB 20 04 FB A9 30 A2 FE 20 C4 -FA 20 3A F3 C9 00 20 62 FC D0 03 4C 98 F2 A9 29 -A2 FE 20 C4 FA 4C 2E F3 A9 20 A2 FE 20 C4 FA A0 -05 20 71 FB 20 B5 FB AD 00 92 AE 01 92 20 F7 FC -A9 0C 20 82 FB 20 96 F1 A0 07 91 04 A0 07 A2 00 -B1 04 C9 00 20 68 FC D0 03 4C DC F2 A0 06 A2 00 -B1 04 C9 FE 20 68 FC F0 03 4C E5 F2 A2 00 A9 00 +00 60 AD E7 EF A2 00 60 60 20 F4 FA A2 00 86 06 +86 07 A9 00 20 8B FB 20 DA FA A9 06 A2 FE 20 9A +FA 20 3A F3 C9 00 20 38 FC D0 03 4C 98 F2 A9 FF +A2 FD 20 9A FA 4C 2E F3 A9 F6 A2 FD 20 9A FA A0 +05 20 47 FB 20 8B FB AD 00 92 AE 01 92 20 CD FC +A9 0C 20 58 FB 20 96 F1 A0 07 91 04 A0 07 A2 00 +B1 04 C9 00 20 3E FC D0 03 4C DC F2 A0 06 A2 00 +B1 04 C9 FE 20 3E FC F0 03 4C E5 F2 A2 00 A9 00 D0 03 4C E9 F2 A2 00 A9 01 D0 03 4C FA F2 AD 00 -92 AE 01 92 20 E6 F5 4C 2B F3 A0 06 A2 00 B1 04 -A2 00 29 F0 20 49 FA D0 03 4C 16 F3 A9 29 A2 FE -20 C4 FA 4C 2B F3 A9 11 A2 FE 20 F7 FC A0 08 A2 -00 B1 04 20 F7 FC A0 04 20 90 FA 6C 00 92 4C 31 -F3 4C 31 F3 A0 0C 20 2F FA 60 20 2B FB A9 00 20 -E1 FC 20 6E F1 4C 71 F3 A0 00 A2 00 18 A9 01 71 -04 91 04 A0 00 A2 00 B1 04 C9 FF 20 68 FC D0 03 -4C 71 F3 A9 4F A2 FE 20 C4 FA A2 00 A9 01 4C 52 -F4 20 56 F4 A0 01 91 04 C9 01 20 62 FC D0 C9 A9 -01 20 82 FB 20 73 F4 A0 01 A2 00 B1 04 C9 01 20 -62 FC D0 03 4C A5 F3 A9 46 A2 FE 20 C4 FA A2 00 -A9 01 4C 52 F4 A0 05 A2 00 B1 04 C9 AA 20 62 FC -D0 03 4C BC F3 A2 00 A9 01 4C 52 F4 A2 00 A9 00 -A0 00 91 04 A0 00 A2 00 B1 04 C9 FF 20 68 FC D0 -03 4C E2 F3 A9 37 A2 FE 20 C4 FA A2 00 A9 01 4C -52 F4 20 95 F5 A0 01 91 04 A0 01 A2 00 B1 04 C9 -02 20 81 FC D0 03 4C 00 F4 20 B2 F5 A0 01 91 04 +92 AE 01 92 20 BB F5 4C 2B F3 A0 06 A2 00 B1 04 +A2 00 29 F0 20 1F FA D0 03 4C 16 F3 A9 FF A2 FD +20 9A FA 4C 2B F3 A9 E7 A2 FD 20 CD FC A0 08 A2 +00 B1 04 20 CD FC A0 04 20 66 FA 6C 00 92 4C 31 +F3 4C 31 F3 A0 0C 20 05 FA 60 20 01 FB A9 00 20 +B7 FC 20 6E F1 4C 71 F3 A0 00 A2 00 18 A9 01 71 +04 91 04 A0 00 A2 00 B1 04 C9 FF 20 3E FC D0 03 +4C 71 F3 A9 25 A2 FE 20 9A FA A2 00 A9 01 4C 27 +F4 20 2B F4 A0 01 91 04 C9 01 20 38 FC D0 C9 A9 +01 20 58 FB 20 48 F4 A0 01 A2 00 B1 04 C9 01 20 +38 FC D0 03 4C A5 F3 A9 1C A2 FE 20 9A FA A2 00 +A9 01 4C 27 F4 A0 05 A2 00 B1 04 C9 AA 20 38 FC +D0 03 4C BC F3 A2 00 A9 01 4C 27 F4 A2 00 A9 00 +A0 00 91 04 A0 00 A2 00 B1 04 C9 FF 20 3E FC D0 +03 4C E2 F3 A9 0D A2 FE 20 9A FA A2 00 A9 01 4C +27 F4 20 6A F5 A0 01 91 04 A0 01 A2 00 B1 04 C9 +02 20 57 FC D0 03 4C 00 F4 20 87 F5 A0 01 91 04 A0 00 A2 00 18 A9 01 71 04 91 04 A0 01 A2 00 B1 -04 C9 00 20 62 FC D0 AC A2 00 A9 00 A0 06 20 0F -FD A0 07 20 68 FB E0 03 D0 02 C9 E8 20 81 FC F0 -03 4C 37 F4 4C 43 F4 A0 06 A2 00 A9 01 20 1F FA -4C 21 F4 A9 01 20 82 FB 20 1B F5 A2 00 A9 00 4C -52 F4 20 58 FB 60 A2 00 A9 00 20 E1 FC A2 00 86 -06 86 07 A9 00 20 B5 FB A2 00 A9 94 20 43 F1 4C -72 F4 60 20 F7 FC A2 00 A9 FF 20 3F F2 A2 00 A9 -00 20 33 F2 A2 00 A9 FF 20 3F F2 A2 00 A9 08 20 -E1 FC A2 01 A9 00 85 06 A9 00 85 07 A9 AA 20 B5 -FB A2 00 A9 86 20 CE F0 A0 01 20 68 FB 20 25 F1 -A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 39 F2 A2 00 -A9 FF 20 3F F2 20 40 FB 60 20 F7 FC A2 00 A9 FF -20 3F F2 A2 00 A9 00 20 33 F2 A2 00 A9 FF 20 3F -F2 A2 00 A9 0D 20 E1 FC A2 00 86 06 86 07 A9 00 -20 B5 FB A2 00 A9 00 20 CE F0 A0 01 20 68 FB 20 -FA F0 A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 39 F2 -A2 00 A9 FF 20 3F F2 20 40 FB 60 20 F7 FC 20 FB -FA A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 A2 -00 A9 FF 20 3F F2 A0 00 91 04 A0 00 A2 00 B1 04 -C9 FF 20 62 FC D0 03 4C 5B F5 4C 4D F5 A2 00 A9 -FF 20 3F F2 C9 FF 20 62 FC D0 F2 A2 00 A9 3A 20 -E1 FC A2 00 86 06 86 07 A9 00 20 B5 FB A2 00 A9 -00 20 CE F0 A0 02 20 68 FB 20 25 F1 A2 00 A9 FF -20 3F F2 A2 00 A9 00 20 39 F2 A2 00 A9 FF 20 3F -F2 20 4E FB 60 A2 00 A9 37 20 E1 FC A2 00 86 06 -86 07 A9 00 20 B5 FB A2 00 A9 00 20 43 F1 4C B1 -F5 60 A2 00 A9 29 20 E1 FC A2 00 86 06 A9 40 85 -07 A9 00 20 B5 FB A2 00 A9 00 20 43 F1 4C D0 F5 -60 20 F7 FC 20 1E FB A0 03 A2 00 B1 04 4C E0 F5 -A0 0E 20 2F FA 60 20 F7 FC A9 00 20 E1 FC 20 04 -FB A2 00 A9 00 A0 00 20 0F FD A0 01 20 68 FB E0 -02 20 81 FC F0 03 4C 0C F6 4C 6E F6 A9 58 A2 FE -20 F7 FC A0 06 20 68 FB A0 00 20 5D FB 20 F7 FC -A0 07 A2 00 A9 01 20 1F FA A0 04 20 90 FA A0 02 -A2 00 B1 04 C9 1F 20 68 FC D0 03 4C 50 F6 A9 5C -A2 FE 20 C4 FA A2 00 A9 00 A0 02 91 04 4C 62 F6 -A2 00 A9 20 20 68 F0 A0 02 A2 00 18 A9 01 71 04 -91 04 A0 00 A2 00 A9 01 20 1F FA 4C FA F5 A9 5C -A2 FE 20 C4 FA 20 53 FB 60 A0 00 B1 1A E6 1A D0 -02 E6 1B 60 AD 4A 92 8D 45 92 20 25 F7 A9 45 A2 -92 20 F7 FC 20 D8 FC 4C 02 92 A5 18 38 E9 02 85 -18 B0 02 C6 19 60 AD 4F 92 D0 11 20 C3 F6 4C 42 -FA AD 4F 92 D0 06 20 C3 F6 4C 3C FA 20 C3 F6 85 -06 86 07 20 9A F6 A0 01 B1 18 AA 88 B1 18 60 A0 -00 84 0C 84 0D B1 1A 38 E9 30 90 2C C9 0A B0 28 -20 7D F6 48 A5 0C A6 0D 06 0C 26 0D 06 0C 26 0D -65 0C 85 0C 8A 65 0D 85 0D 06 0C 26 0D 68 65 0C -85 0C 90 D1 E6 0D B0 CD A5 0C A6 0D 60 AC 51 92 -EE 51 92 99 52 92 60 A9 52 A2 92 18 6D 51 92 90 -01 E8 4C F7 FC A5 1C A6 1D 4C F7 FC 20 84 F6 EE -4B 92 D0 F8 EE 4C 92 D0 F3 60 20 25 F7 AD 66 92 -AE 67 92 20 F7 FC AD 68 92 AE 69 92 20 F7 FC 4C -02 92 84 0C 20 B5 FB 20 17 F7 A5 0C 4C E5 FB 84 -0C 20 B5 FB 20 17 F7 A5 0C 4C 26 FC 48 A0 05 B9 -18 00 99 3F 92 88 10 F7 68 85 18 86 19 20 38 FB -85 1A 86 1B 20 38 FB 85 1C 86 1D A9 00 A8 91 1C -C8 91 1C C8 B1 1C 8D 03 92 C8 B1 1C 8D 04 92 A5 -1A 85 0C A5 1B 85 0D A0 00 B1 1A F0 0B C9 25 F0 -07 C8 D0 F5 E6 1B D0 F1 98 18 65 1A 85 1A 90 02 -E6 1B 38 E5 0C 85 0E A5 1B E5 0D 85 0F 05 0E F0 -25 20 1E FB A0 05 A5 1D 91 04 88 A5 1C 91 04 88 -A5 0D 91 04 88 A5 0C 91 04 88 A5 0F 91 04 88 A5 -0E 91 04 20 02 92 20 79 F6 AA D0 0B A2 05 BD 3F -92 95 18 CA 10 F8 60 C9 25 D0 09 B1 1A C9 25 D0 -09 20 7D F6 20 87 F6 4C 9F F7 A9 00 A2 0B 9D 46 -92 CA 10 FA B1 1A C9 2D D0 05 8E 46 92 F0 19 C9 -2B D0 05 8E 47 92 F0 10 C9 20 D0 05 8E 48 92 F0 -07 C9 23 D0 09 8E 49 92 20 7D F6 4C 24 F8 A2 20 -C9 30 D0 06 AA 20 7D F6 B1 1A 8E 4A 92 C9 2A D0 -09 20 7D F6 20 C3 F6 4C 6D F8 20 CF F6 8D 4B 92 -8E 4C 92 8C 4D 92 8C 4E 92 B1 1A C9 2E D0 1B 20 -7D F6 B1 1A C9 2A D0 09 20 7D F6 20 C3 F6 4C 94 -F8 20 CF F6 8D 4D 92 8E 4E 92 B1 1A C9 7A F0 19 -C9 68 F0 15 C9 74 F0 11 C9 6A F0 08 C9 4C F0 04 -C9 6C D0 0B A9 FF 8D 4F 92 20 7D F6 4C 9A F8 8C -51 92 A2 52 8E 66 92 A2 92 8E 67 92 20 7D F6 C9 -63 D0 0D 20 C3 F6 8D 52 92 A2 00 A9 01 4C C6 F9 -C9 64 F0 04 C9 69 D0 2D A2 00 AD 48 92 F0 02 A2 -20 AD 47 92 F0 02 A2 2B 8E 50 92 20 B1 F6 A4 07 -30 0B AC 50 92 F0 06 8C 52 92 EE 51 92 A0 0A 20 -52 F7 4C BD F9 C9 6E D0 15 20 C3 F6 85 0C 86 0D -A0 00 B1 1C 91 0C C8 B1 1C 91 0C 4C 9F F7 C9 6F -D0 27 20 B1 F6 AC 49 92 F0 17 48 86 14 05 14 05 -06 05 07 0D 4D 92 0D 4E 92 F0 06 A9 30 20 0D F7 -68 A0 08 20 52 F7 4C BD F9 C9 70 D0 0D A2 00 8E -4F 92 E8 8E 49 92 A9 78 D0 27 C9 73 D0 0C 20 C3 -F6 8D 66 92 8E 67 92 4C BD F9 C9 75 D0 0B 20 A6 -F6 A0 0A 20 5F F7 4C BD F9 C9 78 F0 04 C9 58 D0 -29 48 AD 49 92 F0 0A A9 30 20 0D F7 A9 58 20 0D -F7 20 A6 F6 A0 10 20 5F F7 68 C9 78 D0 09 AD 66 -92 AE 67 92 20 4F FD 4C BD F9 4C 9F F7 AD 66 92 -AE 67 92 20 39 FD 8D 68 92 8E 69 92 AD 4D 92 0D -4E 92 F0 15 AE 4D 92 EC 68 92 AD 4E 92 A8 ED 69 -92 B0 06 8E 68 92 8C 69 92 38 AD 4B 92 ED 68 92 -AA AD 4C 92 ED 69 92 B0 03 A9 00 AA 49 FF 8D 4C -92 8A 49 FF 8D 4B 92 AD 46 92 D0 03 20 2F F7 20 -3A F7 AD 46 92 F0 03 20 2F F7 4C 9F F7 A0 00 18 -71 04 91 04 48 C8 8A 71 04 91 04 AA 68 60 C8 48 -18 98 65 04 85 04 90 02 E6 05 68 60 A0 FF E0 80 -B0 02 A0 00 84 06 84 07 60 E0 00 D0 06 AA D0 03 -A9 01 60 A2 00 8A 60 A0 00 F0 07 A9 52 A2 F0 4C -05 92 60 A9 00 85 0C A9 F0 85 0D A9 00 85 0E A9 -92 85 0F A2 CD A9 FF 85 14 A0 00 E8 F0 0D B1 0C -91 0E C8 D0 F6 E6 0D E6 0F D0 F0 E6 14 D0 EF 60 -8C 6A 92 88 88 98 18 65 04 85 0C A6 05 90 01 E8 -86 0D A0 01 B1 0C AA 88 B1 0C 20 F7 FC A5 0C A6 -0D 20 BE FD AC 6A 92 4C 2F FA 85 0C 86 0D 20 75 -F0 4C C8 FA 85 0C 86 0D A0 00 B1 0C F0 0E C8 84 -14 20 68 F0 A4 14 D0 F2 E6 0D D0 EE 60 E0 00 D0 -15 4A AA BD 85 FE 90 05 4A 4A 4A 4A 18 29 0F AA -BD 7A FE A2 00 60 38 A9 00 AA 60 A4 04 D0 02 C6 -05 C6 04 60 A5 04 38 E9 02 85 04 90 01 60 C6 05 -60 A5 04 38 E9 04 85 04 90 01 60 C6 05 60 A5 04 -38 E9 06 85 04 90 01 60 C6 05 60 A5 04 38 E9 07 -85 04 90 01 60 C6 05 60 A0 01 B1 04 AA 88 B1 04 -E6 04 F0 05 E6 04 F0 03 60 E6 04 E6 05 60 A0 03 -4C 2F FA A0 05 4C 2F FA A0 08 4C 2F FA 85 0C 86 -0D A2 00 B1 0C 60 A0 01 B1 04 AA 88 B1 04 60 A0 -03 B1 04 85 07 88 B1 04 85 06 88 B1 04 AA 88 B1 -04 60 A2 00 18 65 04 48 8A 65 05 AA 68 60 18 49 -FF 69 01 48 8A 49 FF 69 00 AA A5 06 49 FF 69 00 -85 06 A5 07 49 FF 69 00 85 07 68 60 A9 00 AA A0 -00 84 06 84 07 48 20 11 FB A0 03 A5 07 91 04 88 -A5 06 91 04 88 8A 91 04 68 88 91 04 60 85 14 20 -38 FB 85 0E 86 0F 85 10 86 11 20 CA FC 20 38 FB -85 06 86 07 60 20 CD FB A6 07 A4 14 C0 0A D0 39 -A5 06 05 0D 05 0C D0 11 E0 80 D0 0D A0 0B B9 6E -FE 91 0E 88 10 F8 4C 5D FC 8A 10 1D A9 2D A0 00 -91 0E E6 0E D0 02 E6 0F A5 0C A6 0D 20 8E FB 85 -0C 86 0D 4C 29 FC 20 CD FB A9 00 48 A0 20 A9 00 -06 0C 26 0D 26 06 26 07 2A C5 14 90 04 E5 14 E6 -0C 88 D0 EC A8 B9 5E FE 48 A5 0C 05 0D 05 06 05 -07 D0 D9 A0 00 68 91 0E F0 03 C8 D0 F8 A5 10 A6 -11 60 D0 06 A2 00 8A 60 D0 FA A2 00 A9 01 60 F0 -F9 30 F7 A2 00 8A 60 F0 02 10 EF A2 00 8A 60 F0 -E9 90 E7 A2 00 8A 60 F0 DB A2 00 8A 2A 60 20 B7 -FC A6 11 F0 13 B1 0C 91 0E C8 B1 0C 91 0E C8 D0 -F4 E6 0D E6 0F CA D0 ED A6 10 F0 08 B1 0C 91 0E -C8 CA D0 F8 4C 38 FB 85 10 86 11 20 CA FC C8 B1 -04 AA 86 0F 88 B1 04 85 0E 60 A0 01 B1 04 85 0D -88 B1 04 85 0C 4C 40 FB A9 01 4C F5 FC A0 00 B1 -04 A4 04 F0 07 C6 04 A0 00 91 04 60 C6 05 C6 04 -91 04 60 A9 00 A2 00 48 A5 04 38 E9 02 85 04 B0 -02 C6 05 A0 01 8A 91 04 68 88 91 04 60 A0 00 91 -04 C8 48 8A 91 04 68 60 85 0E 86 0F 20 CA FC B1 -0C D1 0E D0 0C AA F0 10 C8 D0 F4 E6 0D E6 0F D0 -EE B0 03 A2 FF 60 A2 01 60 85 0E 86 0F A2 00 A0 -00 B1 0E F0 08 C8 D0 F9 E6 0F E8 D0 F4 98 60 85 -0C 86 0D 85 0E 86 0F A0 00 B1 0C F0 14 20 E1 FA -29 02 F0 06 B1 0C 69 20 91 0C C8 D0 EC E6 0D D0 -E8 A5 0E A6 0F 60 20 38 FB 85 0E 86 0F E8 8E 31 -92 AA E8 8E 30 92 20 CA FC 20 38 FB 85 10 86 11 -A0 00 84 14 B1 10 18 65 0E 91 10 C8 B1 10 65 0F -91 10 CE 30 92 F0 11 A4 14 B1 0C C8 D0 02 E6 0D -84 14 20 68 F0 4C A2 FD CE 31 92 D0 EA 60 85 0C -86 0D A9 00 8D 2A 92 8D 2B 92 A0 01 B1 04 AA 88 -B1 04 20 F7 FC A0 02 A9 2A 91 04 C8 A9 92 91 04 -A5 0C A6 0D 20 6C F7 AD 2A 92 AE 2B 92 60 A9 32 -85 0C A9 92 85 0D A9 00 A8 A2 00 F0 0A 91 0C C8 -D0 FB E6 0D CA D0 F6 C0 39 F0 05 91 0C C8 D0 F7 -60 62 61 64 20 74 6F 6B 65 6E 3A 20 25 78 0A 00 -53 75 63 63 65 73 73 0A 00 45 72 72 6F 72 0A 00 -53 74 61 72 74 0A 00 6F 70 5F 63 6F 6E 64 20 65 -72 72 6F 72 0A 00 49 46 20 43 6F 6E 64 0A 00 47 -6F 20 49 44 4C 45 0A 00 25 32 78 00 0A 00 30 31 -32 33 34 35 36 37 38 39 41 42 43 44 45 46 2D 32 -31 34 37 34 38 33 36 34 38 00 00 01 02 0C 09 0A -10 40 50 A0 D0 66 66 66 66 A6 88 88 66 66 66 66 -66 66 66 66 66 09 00 00 00 00 00 00 00 33 33 33 -33 33 00 00 00 50 55 55 25 22 22 22 22 22 22 22 -22 22 02 00 00 40 44 44 14 11 11 11 11 11 11 11 -11 11 01 00 70 00 00 00 00 00 00 00 00 00 00 00 +04 C9 00 20 38 FC D0 AC A9 01 20 58 FB 20 F0 F4 +A2 00 A9 00 4C 27 F4 20 2E FB 60 A2 00 A9 00 20 +B7 FC A2 00 86 06 86 07 A9 00 20 8B FB A2 00 A9 +94 20 43 F1 4C 47 F4 60 20 CD FC A2 00 A9 FF 20 +3F F2 A2 00 A9 00 20 33 F2 A2 00 A9 FF 20 3F F2 +A2 00 A9 08 20 B7 FC A2 01 A9 00 85 06 A9 00 85 +07 A9 AA 20 8B FB A2 00 A9 86 20 CE F0 A0 01 20 +3E FB 20 25 F1 A2 00 A9 FF 20 3F F2 A2 00 A9 00 +20 39 F2 A2 00 A9 FF 20 3F F2 20 16 FB 60 20 CD +FC A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 A2 +00 A9 FF 20 3F F2 A2 00 A9 0D 20 B7 FC A2 00 86 +06 86 07 A9 00 20 8B FB A2 00 A9 00 20 CE F0 A0 +01 20 3E FB 20 FA F0 A2 00 A9 FF 20 3F F2 A2 00 +A9 00 20 39 F2 A2 00 A9 FF 20 3F F2 20 16 FB 60 +20 CD FC 20 D1 FA A2 00 A9 FF 20 3F F2 A2 00 A9 +00 20 33 F2 A2 00 A9 FF 20 3F F2 A0 00 91 04 A0 +00 A2 00 B1 04 C9 FF 20 38 FC D0 03 4C 30 F5 4C +22 F5 A2 00 A9 FF 20 3F F2 C9 FF 20 38 FC D0 F2 +A2 00 A9 3A 20 B7 FC A2 00 86 06 86 07 A9 00 20 +8B FB A2 00 A9 00 20 CE F0 A0 02 20 3E FB 20 25 +F1 A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 39 F2 A2 +00 A9 FF 20 3F F2 20 24 FB 60 A2 00 A9 37 20 B7 +FC A2 00 86 06 86 07 A9 00 20 8B FB A2 00 A9 00 +20 43 F1 4C 86 F5 60 A2 00 A9 29 20 B7 FC A2 00 +86 06 A9 40 85 07 A9 00 20 8B FB A2 00 A9 00 20 +43 F1 4C A5 F5 60 20 CD FC 20 F4 FA A0 03 A2 00 +B1 04 4C B5 F5 A0 0E 20 05 FA 60 20 CD FC A9 00 +20 B7 FC 20 DA FA A2 00 A9 00 A0 00 20 E5 FC A0 +01 20 3E FB E0 02 20 57 FC F0 03 4C E1 F5 4C 43 +F6 A9 2E A2 FE 20 CD FC A0 06 20 3E FB A0 00 20 +33 FB 20 CD FC A0 07 A2 00 A9 01 20 F5 F9 A0 04 +20 66 FA A0 02 A2 00 B1 04 C9 1F 20 3E FC D0 03 +4C 25 F6 A9 32 A2 FE 20 9A FA A2 00 A9 00 A0 02 +91 04 4C 37 F6 A2 00 A9 20 20 68 F0 A0 02 A2 00 +18 A9 01 71 04 91 04 A0 00 A2 00 A9 01 20 F5 F9 +4C CF F5 A9 32 A2 FE 20 9A FA 20 29 FB 60 A0 00 +B1 1A E6 1A D0 02 E6 1B 60 AD 4A 92 8D 45 92 20 +FA F6 A9 45 A2 92 20 CD FC 20 AE FC 4C 02 92 A5 +18 38 E9 02 85 18 B0 02 C6 19 60 AD 4F 92 D0 11 +20 98 F6 4C 18 FA AD 4F 92 D0 06 20 98 F6 4C 12 +FA 20 98 F6 85 06 86 07 20 6F F6 A0 01 B1 18 AA +88 B1 18 60 A0 00 84 0C 84 0D B1 1A 38 E9 30 90 +2C C9 0A B0 28 20 52 F6 48 A5 0C A6 0D 06 0C 26 +0D 06 0C 26 0D 65 0C 85 0C 8A 65 0D 85 0D 06 0C +26 0D 68 65 0C 85 0C 90 D1 E6 0D B0 CD A5 0C A6 +0D 60 AC 51 92 EE 51 92 99 52 92 60 A9 52 A2 92 +18 6D 51 92 90 01 E8 4C CD FC A5 1C A6 1D 4C CD +FC 20 59 F6 EE 4B 92 D0 F8 EE 4C 92 D0 F3 60 20 +FA F6 AD 66 92 AE 67 92 20 CD FC AD 68 92 AE 69 +92 20 CD FC 4C 02 92 84 0C 20 8B FB 20 EC F6 A5 +0C 4C BB FB 84 0C 20 8B FB 20 EC F6 A5 0C 4C FC +FB 48 A0 05 B9 18 00 99 3F 92 88 10 F7 68 85 18 +86 19 20 0E FB 85 1A 86 1B 20 0E FB 85 1C 86 1D +A9 00 A8 91 1C C8 91 1C C8 B1 1C 8D 03 92 C8 B1 +1C 8D 04 92 A5 1A 85 0C A5 1B 85 0D A0 00 B1 1A +F0 0B C9 25 F0 07 C8 D0 F5 E6 1B D0 F1 98 18 65 +1A 85 1A 90 02 E6 1B 38 E5 0C 85 0E A5 1B E5 0D +85 0F 05 0E F0 25 20 F4 FA A0 05 A5 1D 91 04 88 +A5 1C 91 04 88 A5 0D 91 04 88 A5 0C 91 04 88 A5 +0F 91 04 88 A5 0E 91 04 20 02 92 20 4E F6 AA D0 +0B A2 05 BD 3F 92 95 18 CA 10 F8 60 C9 25 D0 09 +B1 1A C9 25 D0 09 20 52 F6 20 5C F6 4C 74 F7 A9 +00 A2 0B 9D 46 92 CA 10 FA B1 1A C9 2D D0 05 8E +46 92 F0 19 C9 2B D0 05 8E 47 92 F0 10 C9 20 D0 +05 8E 48 92 F0 07 C9 23 D0 09 8E 49 92 20 52 F6 +4C F9 F7 A2 20 C9 30 D0 06 AA 20 52 F6 B1 1A 8E +4A 92 C9 2A D0 09 20 52 F6 20 98 F6 4C 42 F8 20 +A4 F6 8D 4B 92 8E 4C 92 8C 4D 92 8C 4E 92 B1 1A +C9 2E D0 1B 20 52 F6 B1 1A C9 2A D0 09 20 52 F6 +20 98 F6 4C 69 F8 20 A4 F6 8D 4D 92 8E 4E 92 B1 +1A C9 7A F0 19 C9 68 F0 15 C9 74 F0 11 C9 6A F0 +08 C9 4C F0 04 C9 6C D0 0B A9 FF 8D 4F 92 20 52 +F6 4C 6F F8 8C 51 92 A2 52 8E 66 92 A2 92 8E 67 +92 20 52 F6 C9 63 D0 0E 20 98 F6 8D 52 92 A9 00 +8D 53 92 4C 93 F9 C9 64 F0 04 C9 69 D0 2D A2 00 +AD 48 92 F0 02 A2 20 AD 47 92 F0 02 A2 2B 8E 50 +92 20 86 F6 A4 07 30 0B AC 50 92 F0 06 8C 52 92 +EE 51 92 A0 0A 20 27 F7 4C 93 F9 C9 6E D0 15 20 +98 F6 85 0C 86 0D A0 00 B1 1C 91 0C C8 B1 1C 91 +0C 4C 74 F7 C9 6F D0 27 20 86 F6 AC 49 92 F0 17 +48 86 14 05 14 05 06 05 07 0D 4D 92 0D 4E 92 F0 +06 A9 30 20 E2 F6 68 A0 08 20 27 F7 4C 93 F9 C9 +70 D0 0D A2 00 8E 4F 92 E8 8E 49 92 A9 78 D0 27 +C9 73 D0 0C 20 98 F6 8D 66 92 8E 67 92 4C 93 F9 +C9 75 D0 0B 20 7B F6 A0 0A 20 34 F7 4C 93 F9 C9 +78 F0 04 C9 58 D0 29 48 AD 49 92 F0 0A A9 30 20 +E2 F6 A9 58 20 E2 F6 20 7B F6 A0 10 20 34 F7 68 +C9 78 D0 09 AD 66 92 AE 67 92 20 25 FD 4C 93 F9 +4C 74 F7 AD 66 92 AE 67 92 20 0F FD 8D 68 92 8E +69 92 AD 4D 92 0D 4E 92 F0 15 AE 4D 92 EC 68 92 +AD 4E 92 A8 ED 69 92 B0 06 8E 68 92 8C 69 92 38 +AD 4B 92 ED 68 92 AA AD 4C 92 ED 69 92 B0 03 A9 +00 AA 49 FF 8D 4C 92 8A 49 FF 8D 4B 92 AD 46 92 +D0 03 20 04 F7 20 0F F7 AD 46 92 F0 03 20 04 F7 +4C 74 F7 A0 00 18 71 04 91 04 48 C8 8A 71 04 91 +04 AA 68 60 C8 48 18 98 65 04 85 04 90 02 E6 05 +68 60 A0 FF E0 80 B0 02 A0 00 84 06 84 07 60 E0 +00 D0 06 AA D0 03 A9 01 60 A2 00 8A 60 A0 00 F0 +07 A9 52 A2 F0 4C 05 92 60 A9 00 85 0C A9 F0 85 +0D A9 00 85 0E A9 92 85 0F A2 CD A9 FF 85 14 A0 +00 E8 F0 0D B1 0C 91 0E C8 D0 F6 E6 0D E6 0F D0 +F0 E6 14 D0 EF 60 8C 6A 92 88 88 98 18 65 04 85 +0C A6 05 90 01 E8 86 0D A0 01 B1 0C AA 88 B1 0C +20 CD FC A5 0C A6 0D 20 94 FD AC 6A 92 4C 05 FA +85 0C 86 0D 20 75 F0 4C 9E FA 85 0C 86 0D A0 00 +B1 0C F0 0E C8 84 14 20 68 F0 A4 14 D0 F2 E6 0D +D0 EE 60 E0 00 D0 15 4A AA BD 5B FE 90 05 4A 4A +4A 4A 18 29 0F AA BD 50 FE A2 00 60 38 A9 00 AA +60 A4 04 D0 02 C6 05 C6 04 60 A5 04 38 E9 02 85 +04 90 01 60 C6 05 60 A5 04 38 E9 04 85 04 90 01 +60 C6 05 60 A5 04 38 E9 06 85 04 90 01 60 C6 05 +60 A5 04 38 E9 07 85 04 90 01 60 C6 05 60 A0 01 +B1 04 AA 88 B1 04 E6 04 F0 05 E6 04 F0 03 60 E6 +04 E6 05 60 A0 03 4C 05 FA A0 05 4C 05 FA A0 08 +4C 05 FA 85 0C 86 0D A2 00 B1 0C 60 A0 01 B1 04 +AA 88 B1 04 60 A0 03 B1 04 85 07 88 B1 04 85 06 +88 B1 04 AA 88 B1 04 60 A2 00 18 65 04 48 8A 65 +05 AA 68 60 18 49 FF 69 01 48 8A 49 FF 69 00 AA +A5 06 49 FF 69 00 85 06 A5 07 49 FF 69 00 85 07 +68 60 A9 00 AA A0 00 84 06 84 07 48 20 E7 FA A0 +03 A5 07 91 04 88 A5 06 91 04 88 8A 91 04 68 88 +91 04 60 85 14 20 0E FB 85 0E 86 0F 85 10 86 11 +20 A0 FC 20 0E FB 85 06 86 07 60 20 A3 FB A6 07 +A4 14 C0 0A D0 39 A5 06 05 0D 05 0C D0 11 E0 80 +D0 0D A0 0B B9 44 FE 91 0E 88 10 F8 4C 33 FC 8A +10 1D A9 2D A0 00 91 0E E6 0E D0 02 E6 0F A5 0C +A6 0D 20 64 FB 85 0C 86 0D 4C FF FB 20 A3 FB A9 +00 48 A0 20 A9 00 06 0C 26 0D 26 06 26 07 2A C5 +14 90 04 E5 14 E6 0C 88 D0 EC A8 B9 34 FE 48 A5 +0C 05 0D 05 06 05 07 D0 D9 A0 00 68 91 0E F0 03 +C8 D0 F8 A5 10 A6 11 60 D0 06 A2 00 8A 60 D0 FA +A2 00 A9 01 60 F0 F9 30 F7 A2 00 8A 60 F0 02 10 +EF A2 00 8A 60 F0 E9 90 E7 A2 00 8A 60 F0 DB A2 +00 8A 2A 60 20 8D FC A6 11 F0 13 B1 0C 91 0E C8 +B1 0C 91 0E C8 D0 F4 E6 0D E6 0F CA D0 ED A6 10 +F0 08 B1 0C 91 0E C8 CA D0 F8 4C 0E FB 85 10 86 +11 20 A0 FC C8 B1 04 AA 86 0F 88 B1 04 85 0E 60 +A0 01 B1 04 85 0D 88 B1 04 85 0C 4C 16 FB A9 01 +4C CB FC A0 00 B1 04 A4 04 F0 07 C6 04 A0 00 91 +04 60 C6 05 C6 04 91 04 60 A9 00 A2 00 48 A5 04 +38 E9 02 85 04 B0 02 C6 05 A0 01 8A 91 04 68 88 +91 04 60 A0 00 91 04 C8 48 8A 91 04 68 60 85 0E +86 0F 20 A0 FC B1 0C D1 0E D0 0C AA F0 10 C8 D0 +F4 E6 0D E6 0F D0 EE B0 03 A2 FF 60 A2 01 60 85 +0E 86 0F A2 00 A0 00 B1 0E F0 08 C8 D0 F9 E6 0F +E8 D0 F4 98 60 85 0C 86 0D 85 0E 86 0F A0 00 B1 +0C F0 14 20 B7 FA 29 02 F0 06 B1 0C 69 20 91 0C +C8 D0 EC E6 0D D0 E8 A5 0E A6 0F 60 20 0E FB 85 +0E 86 0F E8 8E 31 92 AA E8 8E 30 92 20 A0 FC 20 +0E FB 85 10 86 11 A0 00 84 14 B1 10 18 65 0E 91 +10 C8 B1 10 65 0F 91 10 CE 30 92 F0 11 A4 14 B1 +0C C8 D0 02 E6 0D 84 14 20 68 F0 4C 78 FD CE 31 +92 D0 EA 60 85 0C 86 0D A9 00 8D 2A 92 8D 2B 92 +A0 01 B1 04 AA 88 B1 04 20 CD FC A0 02 A9 2A 91 +04 C8 A9 92 91 04 A5 0C A6 0D 20 41 F7 AD 2A 92 +AE 2B 92 60 A9 32 85 0C A9 92 85 0D A9 00 A8 A2 +00 F0 0A 91 0C C8 D0 FB E6 0D CA D0 F6 C0 39 F0 +05 91 0C C8 D0 F7 60 62 61 64 20 74 6F 6B 65 6E +3A 20 25 78 0A 00 53 75 63 63 65 73 73 0A 00 45 +72 72 6F 72 0A 00 53 74 61 72 74 0A 00 6F 70 5F +63 6F 6E 64 20 65 72 72 6F 72 0A 00 49 46 20 43 +6F 6E 64 0A 00 47 6F 20 49 44 4C 45 0A 00 25 32 +78 00 0A 00 30 31 32 33 34 35 36 37 38 39 41 42 +43 44 45 46 2D 32 31 34 37 34 38 33 36 34 38 00 +00 01 02 0C 09 0A 10 40 50 A0 D0 66 66 66 66 A6 +88 88 66 66 66 66 66 66 66 66 66 09 00 00 00 00 +00 00 00 33 33 33 33 33 00 00 00 50 55 55 25 22 +22 22 22 22 22 22 22 22 02 00 00 40 44 44 14 11 +11 11 11 11 11 11 11 11 01 00 70 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index a0bb1eb..06423f0 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -8,12 +8,14 @@ TEST_PROGRAM_NAME?=loop_test TEST_FOLDER?=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME) TEST_PROGRAM?=$(REPO_TOP)/sw/test_code/$(TEST_PROGRAM_NAME)/$(TEST_PROGRAM_NAME).hex +SD_IMAGE_PATH?=$(REPO_TOP)/sw/script/fs.fat.hex #TODO implement something like sources.list TOP_MODULE=sim_top TARGET=sim_top INIT_MEM=init_hex.mem +SD_IMAGE=sd_image.mem FLAGS=-DSIM -DRTL_SIM all: sim @@ -22,14 +24,19 @@ all: sim sim: $(TARGET) vvp $(TARGET) -fst -$(TARGET): $(INIT_MEM) $(SRCS) +$(TARGET): $(SD_IMAGE) $(INIT_MEM) $(SRCS) iverilog -g2005-sv $(FLAGS) -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS) $(INIT_MEM): $(MAKE) -C $(TEST_FOLDER) cp $(TEST_PROGRAM) ./init_hex.mem +# The script that makes this file uses relative paths +$(SD_IMAGE): $(SD_IMAGE_PATH) + cp $(SD_IMAGE_PATH) $(SD_IMAGE) + .PHONY: clean clean: rm -rf $(TARGET) rm -rf $(INIT_MEM) + rm -rf $(SD_IMAGE) diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index f61e015..2b22de3 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -49,7 +49,7 @@ initial begin button_reset <= '0; repeat(10) @(r_clk_2); button_reset <= '1; - repeat(150000) @(r_clk_2); + repeat(200000) @(r_clk_2); $finish(); end @@ -170,4 +170,4 @@ generate end endgenerate -endmodule \ No newline at end of file +endmodule diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 1c66557..f5b9b89 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 1c66557642a27ad2989c5f2321dd22a6bb7d6855 +Subproject commit f5b9b89ca6e140463430fd279bb8b103eeb0bc39 diff --git a/sw/script/create_verilog_image.sh b/sw/script/create_verilog_image.sh index e95ce0b..323bc45 100644 --- a/sw/script/create_verilog_image.sh +++ b/sw/script/create_verilog_image.sh @@ -36,7 +36,7 @@ sudo umount $V $FILE rmdir $V $TMPMOUNT echo +# Really I want the data width to be 512 bytes long, not 16... echo "$(tput bold setaf 11)Converting Image to Verilog$(tput sgr 0)" -objcopy --input-target=binary --output-target=verilog $FILE $FILE.hex +objcopy --input-target=binary --output-target=verilog --verilog-data-width=1 $FILE $FILE.hex echo "$(tput bold setaf 10)Done!$(tput sgr 0)" - From a5ff9fb5daa7844ba0a7e3b1ebaacf4bef681b7e Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Fri, 6 Oct 2023 12:46:29 -0700 Subject: [PATCH 39/57] Update verilog sd --- hw/efinix_fpga/simulation/src/verilog-sd-emulator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index f5b9b89..5f9ab32 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit f5b9b89ca6e140463430fd279bb8b103eeb0bc39 +Subproject commit 5f9ab3279ca7f9964d5b7b84890dbd7ef6f1277a From d27e442d5e25ed461a84efdb2a1fc109136345aa Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Fri, 6 Oct 2023 13:18:36 -0700 Subject: [PATCH 40/57] Use REPO_TOP in script, call script from makefile --- hw/efinix_fpga/simulation/Makefile | 1 + sw/script/create_verilog_image.sh | 4 ++-- sw/script/format_disk.sh | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index 06423f0..d215b5f 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -33,6 +33,7 @@ $(INIT_MEM): # The script that makes this file uses relative paths $(SD_IMAGE): $(SD_IMAGE_PATH) + sh $(REPO_TOP)/sw/script/create_verilog_image.sh cp $(SD_IMAGE_PATH) $(SD_IMAGE) .PHONY: clean diff --git a/sw/script/create_verilog_image.sh b/sw/script/create_verilog_image.sh index 323bc45..83ac7cf 100644 --- a/sw/script/create_verilog_image.sh +++ b/sw/script/create_verilog_image.sh @@ -1,11 +1,11 @@ #!/bin/bash -BOOTLOADER=../bios/bootloader.bin +BOOTLOADER=$REPO_TOP/sw/bios/bootloader.bin FILE=fs.fat TMPMOUNT=/tmp/lo -FSDIR=../fsdir +FSDIR=$REPO_TOP/sw/fsdir V=-v diff --git a/sw/script/format_disk.sh b/sw/script/format_disk.sh index af66e59..8c77237 100644 --- a/sw/script/format_disk.sh +++ b/sw/script/format_disk.sh @@ -1,6 +1,6 @@ #!/bin/bash -BOOTLOADER=../bios/bootloader.bin +BOOTLOADER=$REPO_TOP/sw/bios/bootloader.bin DEVICE=/dev/mmcblk0 TMPBOOTSECT=/tmp/bootsect TMPMOUNT=/tmp/sd From fe72a4e9ea2be444dd9a3a21718ea937c553368b Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Fri, 6 Oct 2023 13:21:54 -0700 Subject: [PATCH 41/57] Remove dependency on file, since its created anyway --- hw/efinix_fpga/simulation/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index d215b5f..10a0f01 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -32,7 +32,7 @@ $(INIT_MEM): cp $(TEST_PROGRAM) ./init_hex.mem # The script that makes this file uses relative paths -$(SD_IMAGE): $(SD_IMAGE_PATH) +$(SD_IMAGE): sh $(REPO_TOP)/sw/script/create_verilog_image.sh cp $(SD_IMAGE_PATH) $(SD_IMAGE) From 532364b8d2264f269898e067f6354bc148405b06 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Fri, 6 Oct 2023 13:33:21 -0700 Subject: [PATCH 42/57] remove sd from regular sim Figure out how to do this later --- hw/efinix_fpga/simulation/Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/Makefile b/hw/efinix_fpga/simulation/Makefile index 10a0f01..e59b38c 100644 --- a/hw/efinix_fpga/simulation/Makefile +++ b/hw/efinix_fpga/simulation/Makefile @@ -24,7 +24,12 @@ all: sim sim: $(TARGET) vvp $(TARGET) -fst -$(TARGET): $(SD_IMAGE) $(INIT_MEM) $(SRCS) +.PHONY: full_sim +full_sim: $(TARGET) $(SD_IMAGE) + vvp $(TARGET) -fst + + +$(TARGET): $(INIT_MEM) $(SRCS) iverilog -g2005-sv $(FLAGS) -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS) $(INIT_MEM): From fc13114e49133159ec1a4fc35d626acfa40d263a Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 9 Oct 2023 21:07:36 -0700 Subject: [PATCH 43/57] Update verilog sd --- hw/efinix_fpga/simulation/src/verilog-sd-emulator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 5f9ab32..9bd1273 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 5f9ab3279ca7f9964d5b7b84890dbd7ef6f1277a +Subproject commit 9bd1273b7a455d8e6deca4b8e6d6b504231799e2 From 67fa368319cd82ea9ebce846efbb6ecd18930f61 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 9 Oct 2023 21:13:21 -0700 Subject: [PATCH 44/57] Update verilog sd --- hw/efinix_fpga/simulation/src/verilog-sd-emulator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 9bd1273..2f0b80c 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 9bd1273b7a455d8e6deca4b8e6d6b504231799e2 +Subproject commit 2f0b80cf23a7e9e2acea48cb8bb9c7655f18b559 From 7bb2dd9a7faf75573a32c0c2a5fc4224a1370f34 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 9 Oct 2023 22:33:44 -0700 Subject: [PATCH 45/57] Update verilog sd --- hw/efinix_fpga/simulation/src/verilog-sd-emulator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 2f0b80c..281419d 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 2f0b80cf23a7e9e2acea48cb8bb9c7655f18b559 +Subproject commit 281419d6eae00aaf5d797e013a983221cc771f3e From 97622ac3bb46785340c7bd5a6e2c334537926170 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 9 Oct 2023 23:32:55 -0700 Subject: [PATCH 46/57] Update verilog sd --- hw/efinix_fpga/simulation/src/verilog-sd-emulator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 281419d..3b3a8d7 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 281419d6eae00aaf5d797e013a983221cc771f3e +Subproject commit 3b3a8d7d1c774cfbd080c64ba78a72275431f2b3 From 57efb41ae08cc9b18421ce3ec598442f8558c239 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 10 Oct 2023 21:39:10 -0700 Subject: [PATCH 47/57] Increase sim time, update verilog sd --- hw/efinix_fpga/simulation/src/sim_top.sv | 2 +- hw/efinix_fpga/simulation/src/verilog-sd-emulator | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 2b22de3..4d18031 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -49,7 +49,7 @@ initial begin button_reset <= '0; repeat(10) @(r_clk_2); button_reset <= '1; - repeat(200000) @(r_clk_2); + repeat(1000000) @(r_clk_2); $finish(); end diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 3b3a8d7..9f0de55 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 3b3a8d7d1c774cfbd080c64ba78a72275431f2b3 +Subproject commit 9f0de55a0e992ec4187adedde8668a98a96bb7ae From 8e70e5a7c4fcf97bff7ad16db056fd376eab43de Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 10 Oct 2023 21:40:24 -0700 Subject: [PATCH 48/57] Update verilog sd --- hw/efinix_fpga/simulation/src/verilog-sd-emulator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/efinix_fpga/simulation/src/verilog-sd-emulator b/hw/efinix_fpga/simulation/src/verilog-sd-emulator index 9f0de55..390b722 160000 --- a/hw/efinix_fpga/simulation/src/verilog-sd-emulator +++ b/hw/efinix_fpga/simulation/src/verilog-sd-emulator @@ -1 +1 @@ -Subproject commit 9f0de55a0e992ec4187adedde8668a98a96bb7ae +Subproject commit 390b7221dbcd176d3875d95f78ef84ccbd2ada1f From d3ea5ed4d1ada8842481937d00426e7fcd22034c Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 11 Oct 2023 00:59:41 -0700 Subject: [PATCH 49/57] Use udisksctl --- .gitlab-ci.yml | 20 ++ hw/efinix_fpga/init_hex.mem | 332 +++++++++++++++--------------- sw/script/create_verilog_image.sh | 20 +- 3 files changed, 195 insertions(+), 177 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c9d0041..d823e3e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -90,9 +90,29 @@ run sim: - linux - iverilog stage: simulate + artifacts: + paths: + - hw/efinix_fpga/simulation/sim_top.vcd script: - source init_env.sh - cd hw/efinix_fpga/simulation - make sim dependencies: - build sim + +full sim: + tags: + - linux + - iverilog + stage: simulate + artifacts: + paths: + - hw/efinix_fpga/simulation/sim_top.vcd + script: + - source init_env.sh + - cd hw/efinix_fpga/simulation + - make clean + - TEST_PROGRAM=$REPO_TOP/sw/bios/bios.hex TEST_FOLDER=$REPO_TOP/sw/bios make full_sim + dependencies: + - build sim + diff --git a/hw/efinix_fpga/init_hex.mem b/hw/efinix_fpga/init_hex.mem index 2b05a54..65dd39a 100644 --- a/hw/efinix_fpga/init_hex.mem +++ b/hw/efinix_fpga/init_hex.mem @@ -1,9 +1,9 @@ @00000000 00 80 4C 00 00 8D 13 92 8E 14 92 8D 1A 92 8E 1B 92 88 B9 FF FF 8D 24 92 88 B9 FF FF 8D 23 92 8C -26 92 20 FF FF A0 FF D0 E8 60 00 00 4C FD 00 00 -00 00 A2 FF 9A D8 A9 00 85 04 A9 DF 85 05 20 C4 -FD 20 39 FA 20 52 F0 58 20 69 F2 6C FC FF 20 2D +26 92 20 FF FF A0 FF D0 E8 60 00 00 4B FD 00 00 +00 00 A2 FF 9A D8 A9 00 85 04 A9 DF 85 05 20 C3 +FD 20 38 FA 20 52 F0 58 20 69 F2 6C FC FF 20 2C FA 00 A0 00 F0 07 A9 52 A2 F0 4C 05 92 60 AD FF EF A2 00 60 8D FF EF 60 20 4F F2 C9 0A D0 05 A9 0D 20 4F F2 60 DA 5A A8 B2 04 AA A9 1B 20 4F F2 @@ -13,19 +13,19 @@ A9 63 20 4F F2 68 60 40 DA BA 48 E8 E8 BD 00 01 29 10 D0 06 68 FA 20 68 F2 40 68 FA 7C BF F0 C5 F0 C9 F0 CA F0 20 9A F0 40 40 20 68 F0 40 48 A0 04 B1 04 09 40 20 3F F2 88 B1 04 20 3F F2 88 10 -F8 68 09 01 20 3F F2 20 29 FB 60 A2 08 A9 FF 20 +F8 68 09 01 20 3F F2 20 28 FB 60 A2 08 A9 FF 20 3F F2 C9 FF D0 03 CA D0 F4 60 85 0C 86 0D 20 EB -F0 92 0C A9 FF 20 3F F2 A0 01 91 0C 20 16 FB 60 -AA 20 A0 FC A9 FF 20 3F F2 92 0C E6 0C D0 02 E6 +F0 92 0C A9 FF 20 3F F2 A0 01 91 0C 20 15 FB 60 +AA 20 9F FC A9 FF 20 3F F2 92 0C E6 0C D0 02 E6 0D CA D0 F0 60 85 0C 86 0D 20 EB F0 C9 02 B0 12 -E6 0C D0 02 E6 0C A5 0C A6 0D 20 CD FC A9 04 20 +E6 0C D0 02 E6 0C A5 0C A6 0D 20 CC FC A9 04 20 10 F1 60 48 A9 FF 20 3F F2 A9 00 20 33 F2 A9 FF 20 3F F2 68 20 CE F0 20 EB F0 A8 A9 FF 20 3F F2 A9 00 20 39 F2 A9 FF 20 3F F2 98 A2 00 60 A9 00 20 39 F2 20 8B F1 A9 FF 20 3F F2 A9 00 20 39 F2 A2 50 A9 FF 20 3F F2 CA D0 F8 60 A2 01 A9 C8 3A -D0 FD CA D0 F8 60 85 0E 86 0F A9 FF 92 0E 20 A0 -FC A5 04 85 10 A5 05 85 11 20 D1 FA A0 00 B1 10 +D0 FD CA D0 F8 60 85 0E 86 0F A9 FF 92 0E 20 9F +FC A5 04 85 10 A5 05 85 11 20 D0 FA A0 00 B1 10 91 04 C8 B1 10 91 04 C8 B1 10 91 04 C8 B1 10 91 04 A9 FF 20 3F F2 A9 00 20 33 F2 A9 FF 20 3F F2 A9 11 A0 04 91 04 A9 00 20 CE F0 20 EB F0 C9 FF @@ -37,91 +37,91 @@ EB A9 FF 20 3F F2 A9 FF 20 3F F2 A5 15 92 0E A5 F2 68 60 A9 01 8D DB EF 60 9C DB EF 60 A9 00 8D DA EF AD DB EF 30 FB AD D9 EF 60 8D E6 EF 60 48 8D E6 EF AD E7 EF 89 02 D0 F9 68 60 AD E6 EF A2 -00 60 AD E7 EF A2 00 60 60 20 F4 FA A2 00 86 06 -86 07 A9 00 20 8B FB 20 DA FA A9 06 A2 FE 20 9A -FA 20 3A F3 C9 00 20 38 FC D0 03 4C 98 F2 A9 FF -A2 FD 20 9A FA 4C 2E F3 A9 F6 A2 FD 20 9A FA A0 -05 20 47 FB 20 8B FB AD 00 92 AE 01 92 20 CD FC -A9 0C 20 58 FB 20 96 F1 A0 07 91 04 A0 07 A2 00 -B1 04 C9 00 20 3E FC D0 03 4C DC F2 A0 06 A2 00 -B1 04 C9 FE 20 3E FC F0 03 4C E5 F2 A2 00 A9 00 +00 60 AD E7 EF A2 00 60 60 20 F3 FA A2 00 86 06 +86 07 A9 00 20 8A FB 20 D9 FA A9 05 A2 FE 20 99 +FA 20 3A F3 C9 00 20 37 FC D0 03 4C 98 F2 A9 FE +A2 FD 20 99 FA 4C 2E F3 A9 F5 A2 FD 20 99 FA A0 +05 20 46 FB 20 8A FB AD 00 92 AE 01 92 20 CC FC +A9 0C 20 57 FB 20 96 F1 A0 07 91 04 A0 07 A2 00 +B1 04 C9 00 20 3D FC D0 03 4C DC F2 A0 06 A2 00 +B1 04 C9 FE 20 3D FC F0 03 4C E5 F2 A2 00 A9 00 D0 03 4C E9 F2 A2 00 A9 01 D0 03 4C FA F2 AD 00 92 AE 01 92 20 BB F5 4C 2B F3 A0 06 A2 00 B1 04 -A2 00 29 F0 20 1F FA D0 03 4C 16 F3 A9 FF A2 FD -20 9A FA 4C 2B F3 A9 E7 A2 FD 20 CD FC A0 08 A2 -00 B1 04 20 CD FC A0 04 20 66 FA 6C 00 92 4C 31 -F3 4C 31 F3 A0 0C 20 05 FA 60 20 01 FB A9 00 20 -B7 FC 20 6E F1 4C 71 F3 A0 00 A2 00 18 A9 01 71 -04 91 04 A0 00 A2 00 B1 04 C9 FF 20 3E FC D0 03 -4C 71 F3 A9 25 A2 FE 20 9A FA A2 00 A9 01 4C 27 -F4 20 2B F4 A0 01 91 04 C9 01 20 38 FC D0 C9 A9 -01 20 58 FB 20 48 F4 A0 01 A2 00 B1 04 C9 01 20 -38 FC D0 03 4C A5 F3 A9 1C A2 FE 20 9A FA A2 00 -A9 01 4C 27 F4 A0 05 A2 00 B1 04 C9 AA 20 38 FC +A2 00 29 F0 20 1E FA D0 03 4C 16 F3 A9 FE A2 FD +20 99 FA 4C 2B F3 A9 E6 A2 FD 20 CC FC A0 08 A2 +00 B1 04 20 CC FC A0 04 20 65 FA 6C 00 92 4C 31 +F3 4C 31 F3 A0 0C 20 04 FA 60 20 00 FB A9 00 20 +B6 FC 20 6E F1 4C 71 F3 A0 00 A2 00 18 A9 01 71 +04 91 04 A0 00 A2 00 B1 04 C9 FF 20 3D FC D0 03 +4C 71 F3 A9 24 A2 FE 20 99 FA A2 00 A9 01 4C 27 +F4 20 2B F4 A0 01 91 04 C9 01 20 37 FC D0 C9 A9 +01 20 57 FB 20 48 F4 A0 01 A2 00 B1 04 C9 01 20 +37 FC D0 03 4C A5 F3 A9 1B A2 FE 20 99 FA A2 00 +A9 01 4C 27 F4 A0 05 A2 00 B1 04 C9 AA 20 37 FC D0 03 4C BC F3 A2 00 A9 01 4C 27 F4 A2 00 A9 00 -A0 00 91 04 A0 00 A2 00 B1 04 C9 FF 20 3E FC D0 -03 4C E2 F3 A9 0D A2 FE 20 9A FA A2 00 A9 01 4C +A0 00 91 04 A0 00 A2 00 B1 04 C9 FF 20 3D FC D0 +03 4C E2 F3 A9 0C A2 FE 20 99 FA A2 00 A9 01 4C 27 F4 20 6A F5 A0 01 91 04 A0 01 A2 00 B1 04 C9 -02 20 57 FC D0 03 4C 00 F4 20 87 F5 A0 01 91 04 +02 20 56 FC D0 03 4C 00 F4 20 87 F5 A0 01 91 04 A0 00 A2 00 18 A9 01 71 04 91 04 A0 01 A2 00 B1 -04 C9 00 20 38 FC D0 AC A9 01 20 58 FB 20 F0 F4 -A2 00 A9 00 4C 27 F4 20 2E FB 60 A2 00 A9 00 20 -B7 FC A2 00 86 06 86 07 A9 00 20 8B FB A2 00 A9 -94 20 43 F1 4C 47 F4 60 20 CD FC A2 00 A9 FF 20 +04 C9 00 20 37 FC D0 AC A9 01 20 57 FB 20 F0 F4 +A2 00 A9 00 4C 27 F4 20 2D FB 60 A2 00 A9 00 20 +B6 FC A2 00 86 06 86 07 A9 00 20 8A FB A2 00 A9 +94 20 43 F1 4C 47 F4 60 20 CC FC A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 A2 00 A9 FF 20 3F F2 -A2 00 A9 08 20 B7 FC A2 01 A9 00 85 06 A9 00 85 -07 A9 AA 20 8B FB A2 00 A9 86 20 CE F0 A0 01 20 -3E FB 20 25 F1 A2 00 A9 FF 20 3F F2 A2 00 A9 00 -20 39 F2 A2 00 A9 FF 20 3F F2 20 16 FB 60 20 CD +A2 00 A9 08 20 B6 FC A2 01 A9 00 85 06 A9 00 85 +07 A9 AA 20 8A FB A2 00 A9 86 20 CE F0 A0 01 20 +3D FB 20 25 F1 A2 00 A9 FF 20 3F F2 A2 00 A9 00 +20 39 F2 A2 00 A9 FF 20 3F F2 20 15 FB 60 20 CC FC A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 A2 -00 A9 FF 20 3F F2 A2 00 A9 0D 20 B7 FC A2 00 86 -06 86 07 A9 00 20 8B FB A2 00 A9 00 20 CE F0 A0 -01 20 3E FB 20 FA F0 A2 00 A9 FF 20 3F F2 A2 00 -A9 00 20 39 F2 A2 00 A9 FF 20 3F F2 20 16 FB 60 -20 CD FC 20 D1 FA A2 00 A9 FF 20 3F F2 A2 00 A9 +00 A9 FF 20 3F F2 A2 00 A9 0D 20 B6 FC A2 00 86 +06 86 07 A9 00 20 8A FB A2 00 A9 00 20 CE F0 A0 +01 20 3D FB 20 FA F0 A2 00 A9 FF 20 3F F2 A2 00 +A9 00 20 39 F2 A2 00 A9 FF 20 3F F2 20 15 FB 60 +20 CC FC 20 D0 FA A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 A2 00 A9 FF 20 3F F2 A0 00 91 04 A0 -00 A2 00 B1 04 C9 FF 20 38 FC D0 03 4C 30 F5 4C -22 F5 A2 00 A9 FF 20 3F F2 C9 FF 20 38 FC D0 F2 -A2 00 A9 3A 20 B7 FC A2 00 86 06 86 07 A9 00 20 -8B FB A2 00 A9 00 20 CE F0 A0 02 20 3E FB 20 25 +00 A2 00 B1 04 C9 FF 20 37 FC D0 03 4C 30 F5 4C +22 F5 A2 00 A9 FF 20 3F F2 C9 FF 20 37 FC D0 F2 +A2 00 A9 3A 20 B6 FC A2 00 86 06 86 07 A9 00 20 +8A FB A2 00 A9 00 20 CE F0 A0 02 20 3D FB 20 25 F1 A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 39 F2 A2 -00 A9 FF 20 3F F2 20 24 FB 60 A2 00 A9 37 20 B7 -FC A2 00 86 06 86 07 A9 00 20 8B FB A2 00 A9 00 -20 43 F1 4C 86 F5 60 A2 00 A9 29 20 B7 FC A2 00 -86 06 A9 40 85 07 A9 00 20 8B FB A2 00 A9 00 20 -43 F1 4C A5 F5 60 20 CD FC 20 F4 FA A0 03 A2 00 -B1 04 4C B5 F5 A0 0E 20 05 FA 60 20 CD FC A9 00 -20 B7 FC 20 DA FA A2 00 A9 00 A0 00 20 E5 FC A0 -01 20 3E FB E0 02 20 57 FC F0 03 4C E1 F5 4C 43 -F6 A9 2E A2 FE 20 CD FC A0 06 20 3E FB A0 00 20 -33 FB 20 CD FC A0 07 A2 00 A9 01 20 F5 F9 A0 04 -20 66 FA A0 02 A2 00 B1 04 C9 1F 20 3E FC D0 03 -4C 25 F6 A9 32 A2 FE 20 9A FA A2 00 A9 00 A0 02 +00 A9 FF 20 3F F2 20 23 FB 60 A2 00 A9 37 20 B6 +FC A2 00 86 06 86 07 A9 00 20 8A FB A2 00 A9 00 +20 43 F1 4C 86 F5 60 A2 00 A9 29 20 B6 FC A2 00 +86 06 A9 40 85 07 A9 00 20 8A FB A2 00 A9 00 20 +43 F1 4C A5 F5 60 20 CC FC 20 F3 FA A0 03 A2 00 +B1 04 4C B5 F5 A0 0E 20 04 FA 60 20 CC FC A9 00 +20 B6 FC 20 D9 FA A2 00 A9 00 A0 00 20 E4 FC A0 +01 20 3D FB E0 02 20 56 FC F0 03 4C E1 F5 4C 43 +F6 A9 2D A2 FE 20 CC FC A0 06 20 3D FB A0 00 20 +32 FB 20 CC FC A0 07 A2 00 A9 01 20 F4 F9 A0 04 +20 65 FA A0 02 A2 00 B1 04 C9 1F 20 3D FC D0 03 +4C 25 F6 A9 31 A2 FE 20 99 FA A2 00 A9 00 A0 02 91 04 4C 37 F6 A2 00 A9 20 20 68 F0 A0 02 A2 00 -18 A9 01 71 04 91 04 A0 00 A2 00 A9 01 20 F5 F9 -4C CF F5 A9 32 A2 FE 20 9A FA 20 29 FB 60 A0 00 +18 A9 01 71 04 91 04 A0 00 A2 00 A9 01 20 F4 F9 +4C CF F5 A9 31 A2 FE 20 99 FA 20 28 FB 60 A0 00 B1 1A E6 1A D0 02 E6 1B 60 AD 4A 92 8D 45 92 20 -FA F6 A9 45 A2 92 20 CD FC 20 AE FC 4C 02 92 A5 +FA F6 A9 45 A2 92 20 CC FC 20 AD FC 4C 02 92 A5 18 38 E9 02 85 18 B0 02 C6 19 60 AD 4F 92 D0 11 -20 98 F6 4C 18 FA AD 4F 92 D0 06 20 98 F6 4C 12 +20 98 F6 4C 17 FA AD 4F 92 D0 06 20 98 F6 4C 11 FA 20 98 F6 85 06 86 07 20 6F F6 A0 01 B1 18 AA 88 B1 18 60 A0 00 84 0C 84 0D B1 1A 38 E9 30 90 2C C9 0A B0 28 20 52 F6 48 A5 0C A6 0D 06 0C 26 0D 06 0C 26 0D 65 0C 85 0C 8A 65 0D 85 0D 06 0C 26 0D 68 65 0C 85 0C 90 D1 E6 0D B0 CD A5 0C A6 0D 60 AC 51 92 EE 51 92 99 52 92 60 A9 52 A2 92 -18 6D 51 92 90 01 E8 4C CD FC A5 1C A6 1D 4C CD +18 6D 51 92 90 01 E8 4C CC FC A5 1C A6 1D 4C CC FC 20 59 F6 EE 4B 92 D0 F8 EE 4C 92 D0 F3 60 20 -FA F6 AD 66 92 AE 67 92 20 CD FC AD 68 92 AE 69 -92 20 CD FC 4C 02 92 84 0C 20 8B FB 20 EC F6 A5 -0C 4C BB FB 84 0C 20 8B FB 20 EC F6 A5 0C 4C FC +FA F6 AD 66 92 AE 67 92 20 CC FC AD 68 92 AE 69 +92 20 CC FC 4C 02 92 84 0C 20 8A FB 20 EC F6 A5 +0C 4C BA FB 84 0C 20 8A FB 20 EC F6 A5 0C 4C FB FB 48 A0 05 B9 18 00 99 3F 92 88 10 F7 68 85 18 -86 19 20 0E FB 85 1A 86 1B 20 0E FB 85 1C 86 1D +86 19 20 0D FB 85 1A 86 1B 20 0D FB 85 1C 86 1D A9 00 A8 91 1C C8 91 1C C8 B1 1C 8D 03 92 C8 B1 1C 8D 04 92 A5 1A 85 0C A5 1B 85 0D A0 00 B1 1A F0 0B C9 25 F0 07 C8 D0 F5 E6 1B D0 F1 98 18 65 1A 85 1A 90 02 E6 1B 38 E5 0C 85 0E A5 1B E5 0D -85 0F 05 0E F0 25 20 F4 FA A0 05 A5 1D 91 04 88 +85 0F 05 0E F0 25 20 F3 FA A0 05 A5 1D 91 04 88 A5 1C 91 04 88 A5 0D 91 04 88 A5 0C 91 04 88 A5 0F 91 04 88 A5 0E 91 04 20 02 92 20 4E F6 AA D0 0B A2 05 BD 3F 92 95 18 CA 10 F8 60 C9 25 D0 09 @@ -137,102 +137,102 @@ C9 2E D0 1B 20 52 F6 B1 1A C9 2A D0 09 20 52 F6 1A C9 7A F0 19 C9 68 F0 15 C9 74 F0 11 C9 6A F0 08 C9 4C F0 04 C9 6C D0 0B A9 FF 8D 4F 92 20 52 F6 4C 6F F8 8C 51 92 A2 52 8E 66 92 A2 92 8E 67 -92 20 52 F6 C9 63 D0 0E 20 98 F6 8D 52 92 A9 00 -8D 53 92 4C 93 F9 C9 64 F0 04 C9 69 D0 2D A2 00 -AD 48 92 F0 02 A2 20 AD 47 92 F0 02 A2 2B 8E 50 -92 20 86 F6 A4 07 30 0B AC 50 92 F0 06 8C 52 92 -EE 51 92 A0 0A 20 27 F7 4C 93 F9 C9 6E D0 15 20 -98 F6 85 0C 86 0D A0 00 B1 1C 91 0C C8 B1 1C 91 -0C 4C 74 F7 C9 6F D0 27 20 86 F6 AC 49 92 F0 17 -48 86 14 05 14 05 06 05 07 0D 4D 92 0D 4E 92 F0 -06 A9 30 20 E2 F6 68 A0 08 20 27 F7 4C 93 F9 C9 -70 D0 0D A2 00 8E 4F 92 E8 8E 49 92 A9 78 D0 27 -C9 73 D0 0C 20 98 F6 8D 66 92 8E 67 92 4C 93 F9 -C9 75 D0 0B 20 7B F6 A0 0A 20 34 F7 4C 93 F9 C9 -78 F0 04 C9 58 D0 29 48 AD 49 92 F0 0A A9 30 20 -E2 F6 A9 58 20 E2 F6 20 7B F6 A0 10 20 34 F7 68 -C9 78 D0 09 AD 66 92 AE 67 92 20 25 FD 4C 93 F9 -4C 74 F7 AD 66 92 AE 67 92 20 0F FD 8D 68 92 8E -69 92 AD 4D 92 0D 4E 92 F0 15 AE 4D 92 EC 68 92 -AD 4E 92 A8 ED 69 92 B0 06 8E 68 92 8C 69 92 38 -AD 4B 92 ED 68 92 AA AD 4C 92 ED 69 92 B0 03 A9 -00 AA 49 FF 8D 4C 92 8A 49 FF 8D 4B 92 AD 46 92 -D0 03 20 04 F7 20 0F F7 AD 46 92 F0 03 20 04 F7 -4C 74 F7 A0 00 18 71 04 91 04 48 C8 8A 71 04 91 -04 AA 68 60 C8 48 18 98 65 04 85 04 90 02 E6 05 -68 60 A0 FF E0 80 B0 02 A0 00 84 06 84 07 60 E0 -00 D0 06 AA D0 03 A9 01 60 A2 00 8A 60 A0 00 F0 -07 A9 52 A2 F0 4C 05 92 60 A9 00 85 0C A9 F0 85 -0D A9 00 85 0E A9 92 85 0F A2 CD A9 FF 85 14 A0 -00 E8 F0 0D B1 0C 91 0E C8 D0 F6 E6 0D E6 0F D0 -F0 E6 14 D0 EF 60 8C 6A 92 88 88 98 18 65 04 85 -0C A6 05 90 01 E8 86 0D A0 01 B1 0C AA 88 B1 0C -20 CD FC A5 0C A6 0D 20 94 FD AC 6A 92 4C 05 FA -85 0C 86 0D 20 75 F0 4C 9E FA 85 0C 86 0D A0 00 -B1 0C F0 0E C8 84 14 20 68 F0 A4 14 D0 F2 E6 0D -D0 EE 60 E0 00 D0 15 4A AA BD 5B FE 90 05 4A 4A -4A 4A 18 29 0F AA BD 50 FE A2 00 60 38 A9 00 AA -60 A4 04 D0 02 C6 05 C6 04 60 A5 04 38 E9 02 85 -04 90 01 60 C6 05 60 A5 04 38 E9 04 85 04 90 01 -60 C6 05 60 A5 04 38 E9 06 85 04 90 01 60 C6 05 -60 A5 04 38 E9 07 85 04 90 01 60 C6 05 60 A0 01 -B1 04 AA 88 B1 04 E6 04 F0 05 E6 04 F0 03 60 E6 -04 E6 05 60 A0 03 4C 05 FA A0 05 4C 05 FA A0 08 -4C 05 FA 85 0C 86 0D A2 00 B1 0C 60 A0 01 B1 04 -AA 88 B1 04 60 A0 03 B1 04 85 07 88 B1 04 85 06 -88 B1 04 AA 88 B1 04 60 A2 00 18 65 04 48 8A 65 -05 AA 68 60 18 49 FF 69 01 48 8A 49 FF 69 00 AA -A5 06 49 FF 69 00 85 06 A5 07 49 FF 69 00 85 07 -68 60 A9 00 AA A0 00 84 06 84 07 48 20 E7 FA A0 -03 A5 07 91 04 88 A5 06 91 04 88 8A 91 04 68 88 -91 04 60 85 14 20 0E FB 85 0E 86 0F 85 10 86 11 -20 A0 FC 20 0E FB 85 06 86 07 60 20 A3 FB A6 07 -A4 14 C0 0A D0 39 A5 06 05 0D 05 0C D0 11 E0 80 -D0 0D A0 0B B9 44 FE 91 0E 88 10 F8 4C 33 FC 8A -10 1D A9 2D A0 00 91 0E E6 0E D0 02 E6 0F A5 0C -A6 0D 20 64 FB 85 0C 86 0D 4C FF FB 20 A3 FB A9 -00 48 A0 20 A9 00 06 0C 26 0D 26 06 26 07 2A C5 -14 90 04 E5 14 E6 0C 88 D0 EC A8 B9 34 FE 48 A5 -0C 05 0D 05 06 05 07 D0 D9 A0 00 68 91 0E F0 03 -C8 D0 F8 A5 10 A6 11 60 D0 06 A2 00 8A 60 D0 FA -A2 00 A9 01 60 F0 F9 30 F7 A2 00 8A 60 F0 02 10 -EF A2 00 8A 60 F0 E9 90 E7 A2 00 8A 60 F0 DB A2 -00 8A 2A 60 20 8D FC A6 11 F0 13 B1 0C 91 0E C8 -B1 0C 91 0E C8 D0 F4 E6 0D E6 0F CA D0 ED A6 10 -F0 08 B1 0C 91 0E C8 CA D0 F8 4C 0E FB 85 10 86 -11 20 A0 FC C8 B1 04 AA 86 0F 88 B1 04 85 0E 60 -A0 01 B1 04 85 0D 88 B1 04 85 0C 4C 16 FB A9 01 -4C CB FC A0 00 B1 04 A4 04 F0 07 C6 04 A0 00 91 -04 60 C6 05 C6 04 91 04 60 A9 00 A2 00 48 A5 04 -38 E9 02 85 04 B0 02 C6 05 A0 01 8A 91 04 68 88 -91 04 60 A0 00 91 04 C8 48 8A 91 04 68 60 85 0E -86 0F 20 A0 FC B1 0C D1 0E D0 0C AA F0 10 C8 D0 -F4 E6 0D E6 0F D0 EE B0 03 A2 FF 60 A2 01 60 85 -0E 86 0F A2 00 A0 00 B1 0E F0 08 C8 D0 F9 E6 0F -E8 D0 F4 98 60 85 0C 86 0D 85 0E 86 0F A0 00 B1 -0C F0 14 20 B7 FA 29 02 F0 06 B1 0C 69 20 91 0C -C8 D0 EC E6 0D D0 E8 A5 0E A6 0F 60 20 0E FB 85 -0E 86 0F E8 8E 31 92 AA E8 8E 30 92 20 A0 FC 20 -0E FB 85 10 86 11 A0 00 84 14 B1 10 18 65 0E 91 -10 C8 B1 10 65 0F 91 10 CE 30 92 F0 11 A4 14 B1 -0C C8 D0 02 E6 0D 84 14 20 68 F0 4C 78 FD CE 31 -92 D0 EA 60 85 0C 86 0D A9 00 8D 2A 92 8D 2B 92 -A0 01 B1 04 AA 88 B1 04 20 CD FC A0 02 A9 2A 91 -04 C8 A9 92 91 04 A5 0C A6 0D 20 41 F7 AD 2A 92 -AE 2B 92 60 A9 32 85 0C A9 92 85 0D A9 00 A8 A2 -00 F0 0A 91 0C C8 D0 FB E6 0D CA D0 F6 C0 39 F0 -05 91 0C C8 D0 F7 60 62 61 64 20 74 6F 6B 65 6E -3A 20 25 78 0A 00 53 75 63 63 65 73 73 0A 00 45 -72 72 6F 72 0A 00 53 74 61 72 74 0A 00 6F 70 5F -63 6F 6E 64 20 65 72 72 6F 72 0A 00 49 46 20 43 -6F 6E 64 0A 00 47 6F 20 49 44 4C 45 0A 00 25 32 -78 00 0A 00 30 31 32 33 34 35 36 37 38 39 41 42 -43 44 45 46 2D 32 31 34 37 34 38 33 36 34 38 00 -00 01 02 0C 09 0A 10 40 50 A0 D0 66 66 66 66 A6 -88 88 66 66 66 66 66 66 66 66 66 09 00 00 00 00 -00 00 00 33 33 33 33 33 00 00 00 50 55 55 25 22 -22 22 22 22 22 22 22 22 02 00 00 40 44 44 14 11 -11 11 11 11 11 11 11 11 01 00 70 00 00 00 00 00 +92 20 52 F6 C9 63 D0 0D 20 98 F6 8D 52 92 A2 00 +A9 01 4C 9B F9 C9 64 F0 04 C9 69 D0 2D A2 00 AD +48 92 F0 02 A2 20 AD 47 92 F0 02 A2 2B 8E 50 92 +20 86 F6 A4 07 30 0B AC 50 92 F0 06 8C 52 92 EE +51 92 A0 0A 20 27 F7 4C 92 F9 C9 6E D0 15 20 98 +F6 85 0C 86 0D A0 00 B1 1C 91 0C C8 B1 1C 91 0C +4C 74 F7 C9 6F D0 27 20 86 F6 AC 49 92 F0 17 48 +86 14 05 14 05 06 05 07 0D 4D 92 0D 4E 92 F0 06 +A9 30 20 E2 F6 68 A0 08 20 27 F7 4C 92 F9 C9 70 +D0 0D A2 00 8E 4F 92 E8 8E 49 92 A9 78 D0 27 C9 +73 D0 0C 20 98 F6 8D 66 92 8E 67 92 4C 92 F9 C9 +75 D0 0B 20 7B F6 A0 0A 20 34 F7 4C 92 F9 C9 78 +F0 04 C9 58 D0 29 48 AD 49 92 F0 0A A9 30 20 E2 +F6 A9 58 20 E2 F6 20 7B F6 A0 10 20 34 F7 68 C9 +78 D0 09 AD 66 92 AE 67 92 20 24 FD 4C 92 F9 4C +74 F7 AD 66 92 AE 67 92 20 0E FD 8D 68 92 8E 69 +92 AD 4D 92 0D 4E 92 F0 15 AE 4D 92 EC 68 92 AD +4E 92 A8 ED 69 92 B0 06 8E 68 92 8C 69 92 38 AD +4B 92 ED 68 92 AA AD 4C 92 ED 69 92 B0 03 A9 00 +AA 49 FF 8D 4C 92 8A 49 FF 8D 4B 92 AD 46 92 D0 +03 20 04 F7 20 0F F7 AD 46 92 F0 03 20 04 F7 4C +74 F7 A0 00 18 71 04 91 04 48 C8 8A 71 04 91 04 +AA 68 60 C8 48 18 98 65 04 85 04 90 02 E6 05 68 +60 A0 FF E0 80 B0 02 A0 00 84 06 84 07 60 E0 00 +D0 06 AA D0 03 A9 01 60 A2 00 8A 60 A0 00 F0 07 +A9 52 A2 F0 4C 05 92 60 A9 00 85 0C A9 F0 85 0D +A9 00 85 0E A9 92 85 0F A2 CD A9 FF 85 14 A0 00 +E8 F0 0D B1 0C 91 0E C8 D0 F6 E6 0D E6 0F D0 F0 +E6 14 D0 EF 60 8C 6A 92 88 88 98 18 65 04 85 0C +A6 05 90 01 E8 86 0D A0 01 B1 0C AA 88 B1 0C 20 +CC FC A5 0C A6 0D 20 93 FD AC 6A 92 4C 04 FA 85 +0C 86 0D 20 75 F0 4C 9D FA 85 0C 86 0D A0 00 B1 +0C F0 0E C8 84 14 20 68 F0 A4 14 D0 F2 E6 0D D0 +EE 60 E0 00 D0 15 4A AA BD 5A FE 90 05 4A 4A 4A +4A 18 29 0F AA BD 4F FE A2 00 60 38 A9 00 AA 60 +A4 04 D0 02 C6 05 C6 04 60 A5 04 38 E9 02 85 04 +90 01 60 C6 05 60 A5 04 38 E9 04 85 04 90 01 60 +C6 05 60 A5 04 38 E9 06 85 04 90 01 60 C6 05 60 +A5 04 38 E9 07 85 04 90 01 60 C6 05 60 A0 01 B1 +04 AA 88 B1 04 E6 04 F0 05 E6 04 F0 03 60 E6 04 +E6 05 60 A0 03 4C 04 FA A0 05 4C 04 FA A0 08 4C +04 FA 85 0C 86 0D A2 00 B1 0C 60 A0 01 B1 04 AA +88 B1 04 60 A0 03 B1 04 85 07 88 B1 04 85 06 88 +B1 04 AA 88 B1 04 60 A2 00 18 65 04 48 8A 65 05 +AA 68 60 18 49 FF 69 01 48 8A 49 FF 69 00 AA A5 +06 49 FF 69 00 85 06 A5 07 49 FF 69 00 85 07 68 +60 A9 00 AA A0 00 84 06 84 07 48 20 E6 FA A0 03 +A5 07 91 04 88 A5 06 91 04 88 8A 91 04 68 88 91 +04 60 85 14 20 0D FB 85 0E 86 0F 85 10 86 11 20 +9F FC 20 0D FB 85 06 86 07 60 20 A2 FB A6 07 A4 +14 C0 0A D0 39 A5 06 05 0D 05 0C D0 11 E0 80 D0 +0D A0 0B B9 43 FE 91 0E 88 10 F8 4C 32 FC 8A 10 +1D A9 2D A0 00 91 0E E6 0E D0 02 E6 0F A5 0C A6 +0D 20 63 FB 85 0C 86 0D 4C FE FB 20 A2 FB A9 00 +48 A0 20 A9 00 06 0C 26 0D 26 06 26 07 2A C5 14 +90 04 E5 14 E6 0C 88 D0 EC A8 B9 33 FE 48 A5 0C +05 0D 05 06 05 07 D0 D9 A0 00 68 91 0E F0 03 C8 +D0 F8 A5 10 A6 11 60 D0 06 A2 00 8A 60 D0 FA A2 +00 A9 01 60 F0 F9 30 F7 A2 00 8A 60 F0 02 10 EF +A2 00 8A 60 F0 E9 90 E7 A2 00 8A 60 F0 DB A2 00 +8A 2A 60 20 8C FC A6 11 F0 13 B1 0C 91 0E C8 B1 +0C 91 0E C8 D0 F4 E6 0D E6 0F CA D0 ED A6 10 F0 +08 B1 0C 91 0E C8 CA D0 F8 4C 0D FB 85 10 86 11 +20 9F FC C8 B1 04 AA 86 0F 88 B1 04 85 0E 60 A0 +01 B1 04 85 0D 88 B1 04 85 0C 4C 15 FB A9 01 4C +CA FC A0 00 B1 04 A4 04 F0 07 C6 04 A0 00 91 04 +60 C6 05 C6 04 91 04 60 A9 00 A2 00 48 A5 04 38 +E9 02 85 04 B0 02 C6 05 A0 01 8A 91 04 68 88 91 +04 60 A0 00 91 04 C8 48 8A 91 04 68 60 85 0E 86 +0F 20 9F FC B1 0C D1 0E D0 0C AA F0 10 C8 D0 F4 +E6 0D E6 0F D0 EE B0 03 A2 FF 60 A2 01 60 85 0E +86 0F A2 00 A0 00 B1 0E F0 08 C8 D0 F9 E6 0F E8 +D0 F4 98 60 85 0C 86 0D 85 0E 86 0F A0 00 B1 0C +F0 14 20 B6 FA 29 02 F0 06 B1 0C 69 20 91 0C C8 +D0 EC E6 0D D0 E8 A5 0E A6 0F 60 20 0D FB 85 0E +86 0F E8 8E 31 92 AA E8 8E 30 92 20 9F FC 20 0D +FB 85 10 86 11 A0 00 84 14 B1 10 18 65 0E 91 10 +C8 B1 10 65 0F 91 10 CE 30 92 F0 11 A4 14 B1 0C +C8 D0 02 E6 0D 84 14 20 68 F0 4C 77 FD CE 31 92 +D0 EA 60 85 0C 86 0D A9 00 8D 2A 92 8D 2B 92 A0 +01 B1 04 AA 88 B1 04 20 CC FC A0 02 A9 2A 91 04 +C8 A9 92 91 04 A5 0C A6 0D 20 41 F7 AD 2A 92 AE +2B 92 60 A9 32 85 0C A9 92 85 0D A9 00 A8 A2 00 +F0 0A 91 0C C8 D0 FB E6 0D CA D0 F6 C0 39 F0 05 +91 0C C8 D0 F7 60 62 61 64 20 74 6F 6B 65 6E 3A +20 25 78 0A 00 53 75 63 63 65 73 73 0A 00 45 72 +72 6F 72 0A 00 53 74 61 72 74 0A 00 6F 70 5F 63 +6F 6E 64 20 65 72 72 6F 72 0A 00 49 46 20 43 6F +6E 64 0A 00 47 6F 20 49 44 4C 45 0A 00 25 32 78 +00 0A 00 30 31 32 33 34 35 36 37 38 39 41 42 43 +44 45 46 2D 32 31 34 37 34 38 33 36 34 38 00 00 +01 02 0C 09 0A 10 40 50 A0 D0 66 66 66 66 A6 88 +88 66 66 66 66 66 66 66 66 66 09 00 00 00 00 00 +00 00 33 33 33 33 33 00 00 00 50 55 55 25 22 22 +22 22 22 22 22 22 22 02 00 00 40 44 44 14 11 11 +11 11 11 11 11 11 11 01 00 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/sw/script/create_verilog_image.sh b/sw/script/create_verilog_image.sh index 83ac7cf..814bac5 100644 --- a/sw/script/create_verilog_image.sh +++ b/sw/script/create_verilog_image.sh @@ -1,4 +1,3 @@ - #!/bin/bash BOOTLOADER=$REPO_TOP/sw/bios/bootloader.bin @@ -7,6 +6,8 @@ FILE=fs.fat TMPMOUNT=/tmp/lo FSDIR=$REPO_TOP/sw/fsdir +MNT=/run/media/$USER/SUPER6502 + V=-v # Smallest number of blocks where mkfs doesn't complain @@ -22,21 +23,18 @@ echo "$(tput bold setaf 11)Modifying Boot Sector$(tput sgr 0)" dd if=$BOOTLOADER of=$FILE bs=1 conv=notrunc count=11 $STATUS dd if=$BOOTLOADER of=$FILE bs=1 conv=notrunc count=380 seek=71 skip=71 $STATUS -echo "$(tput bold setaf 11)Mounting Device$(tput sgr 0)" -mkdir $V -p $TMPMOUNT -sudo mount $FILE $TMPMOUNT -echo + +LOOP=$(udisksctl loop-setup -f $FILE | grep -o "/dev/loop\([0-9]\)\+") +MNT=$(udisksctl mount -b $LOOP $TMPMOUNT | grep -o "\([A-Za-z/-]*/\)SUPER6502") echo "$(tput bold setaf 11)Copying Files$(tput sgr 0)" -sudo cp $V -r $FSDIR/* $TMPMOUNT +cp $V -r $FSDIR/* $MNT echo -echo "$(tput bold setaf 11)Unmounting Device$(tput sgr 0)" -sudo umount $V $FILE -rmdir $V $TMPMOUNT -echo +udisksctl unmount -b $LOOP + +udisksctl loop-delete -b $LOOP -# Really I want the data width to be 512 bytes long, not 16... echo "$(tput bold setaf 11)Converting Image to Verilog$(tput sgr 0)" objcopy --input-target=binary --output-target=verilog --verilog-data-width=1 $FILE $FILE.hex echo "$(tput bold setaf 10)Done!$(tput sgr 0)" From 4988d458b70c3bf8fbe2e865fcc210309ed1d6d4 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 11 Oct 2023 01:02:41 -0700 Subject: [PATCH 50/57] full sim requires toolchain --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d823e3e..453baae 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -114,5 +114,5 @@ full sim: - make clean - TEST_PROGRAM=$REPO_TOP/sw/bios/bios.hex TEST_FOLDER=$REPO_TOP/sw/bios make full_sim dependencies: - - build sim + - build toolchain From 448d9add896b8ae88576c61d702c7cf3764ba1a6 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 11 Oct 2023 01:06:50 -0700 Subject: [PATCH 51/57] Use repo based path for creating fs image --- sw/script/create_verilog_image.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw/script/create_verilog_image.sh b/sw/script/create_verilog_image.sh index 814bac5..51249fd 100644 --- a/sw/script/create_verilog_image.sh +++ b/sw/script/create_verilog_image.sh @@ -1,7 +1,7 @@ #!/bin/bash BOOTLOADER=$REPO_TOP/sw/bios/bootloader.bin -FILE=fs.fat +FILE=$REPO_TOP/sw/script/fs.fat TMPMOUNT=/tmp/lo FSDIR=$REPO_TOP/sw/fsdir From 673386f9f914aab45ddb1aaf501e42c27c5f0b88 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Thu, 12 Oct 2023 19:32:12 -0700 Subject: [PATCH 52/57] Change clk_2 to clk_cpu --- hw/efinix_fpga/simulation/src/sim_top.sv | 14 +++++++------- hw/efinix_fpga/src/super6502.sv | 24 ++++++++++++------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 4d18031..474af69 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -4,7 +4,7 @@ module sim_top(); `include "include/super6502_sdram_controller_define.vh" -logic r_sysclk, r_sdrclk, r_clk_50, r_clk_2; +logic r_sysclk, r_sdrclk, r_clk_50, r_clk_cpu; // clk_100 initial begin @@ -30,11 +30,11 @@ initial begin end end -// clk_2 +// clk_cpu initial begin - r_clk_2 <= '1; + r_clk_cpu <= '1; forever begin - #250 r_clk_2 <= ~r_clk_2; + #250 r_clk_cpu <= ~r_clk_cpu; end end @@ -47,9 +47,9 @@ logic button_reset; initial begin button_reset <= '0; - repeat(10) @(r_clk_2); + repeat(10) @(r_clk_cpu); button_reset <= '1; - repeat(1000000) @(r_clk_2); + repeat(1000000) @(r_clk_cpu); $finish(); end @@ -101,7 +101,7 @@ super6502 u_dut( .i_sdrclk(r_sdrclk), .i_tACclk(~r_sdrclk), .clk_50(r_clk_50), - .clk_2(r_clk_2), + .clk_cpu(r_clk_cpu), .button_reset(button_reset), .cpu_resb(w_cpu_reset), .cpu_addr(w_cpu_addr), diff --git a/hw/efinix_fpga/src/super6502.sv b/hw/efinix_fpga/src/super6502.sv index b0b1a49..5cdc894 100644 --- a/hw/efinix_fpga/src/super6502.sv +++ b/hw/efinix_fpga/src/super6502.sv @@ -11,7 +11,7 @@ module super6502 input button_reset, input pll_cpu_locked, input clk_50, - input clk_2, + input clk_cpu, input logic [15:0] cpu_addr, output logic [7:0] cpu_data_out, output logic [7:0] cpu_data_oe, @@ -56,11 +56,11 @@ assign cpu_nmib = '1; logic w_wait; assign cpu_rdy = ~w_wait; -assign cpu_phi2 = clk_2; +assign cpu_phi2 = clk_cpu; logic w_sdr_init_done; -always @(posedge clk_2) begin +always @(posedge clk_cpu) begin if (button_reset == '0) begin cpu_resb <= '0; end @@ -124,12 +124,12 @@ end rom #(.DATA_WIDTH(8), .ADDR_WIDTH(12)) u_rom( .addr(cpu_addr[11:0]), - .clk(clk_2), + .clk(clk_cpu), .data(w_rom_data_out) ); leds u_leds( - .clk(clk_2), + .clk(clk_cpu), .i_data(cpu_data_in), .o_data(w_leds_data_out), .cs(w_leds_cs), @@ -140,7 +140,7 @@ leds u_leds( logic w_timer_irqb; timer u_timer( - .clk(clk_2), + .clk(clk_cpu), .reset(~cpu_resb), .i_data(cpu_data_in), .o_data(w_timer_data_out), @@ -151,7 +151,7 @@ timer u_timer( ); multiplier u_multiplier( - .clk(clk_2), + .clk(clk_cpu), .reset(~cpu_resb), .i_data(cpu_data_in), .o_data(w_multiplier_data_out), @@ -161,7 +161,7 @@ multiplier u_multiplier( ); divider_wrapper u_divider( - .clk(clk_2), + .clk(clk_cpu), .divclk(clk_50), .reset(~cpu_resb), .i_data(cpu_data_in), @@ -174,7 +174,7 @@ divider_wrapper u_divider( logic w_uart_irqb; uart_wrapper u_uart( - .clk(clk_2), + .clk(clk_cpu), .clk_50(clk_50), .reset(~cpu_resb), .i_data(cpu_data_in), @@ -188,7 +188,7 @@ uart_wrapper u_uart( ); spi_controller spi_controller( - .i_clk(clk_2), + .i_clk(clk_cpu), .i_rst(~cpu_resb), .i_cs(w_spi_cs), .i_rwb(cpu_rwb), @@ -204,7 +204,7 @@ spi_controller spi_controller( sdram_adapter u_sdram_adapter( - .i_cpuclk(clk_2), + .i_cpuclk(clk_cpu), .i_arst(~button_reset), .i_sysclk(i_sysclk), .i_sdrclk(i_sdrclk), @@ -234,7 +234,7 @@ sdram_adapter u_sdram_adapter( ); interrupt_controller u_interrupt_controller( - .clk(clk_2), + .clk(clk_cpu), .reset(~cpu_resb), .i_data(cpu_data_in), .o_data(w_irq_data_out), From afd8de92cc3f0061d6a917c162b08e37f7a31c04 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 15 Oct 2023 13:12:46 -0700 Subject: [PATCH 53/57] Fix sdram wrapper state machine --- hw/efinix_fpga/simulation/src/sim_top.sv | 6 ++- hw/efinix_fpga/src/sdram_adapter.sv | 63 ++++++++++++++---------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 474af69..98053fb 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -34,10 +34,14 @@ end initial begin r_clk_cpu <= '1; forever begin - #250 r_clk_cpu <= ~r_clk_cpu; + #125 r_clk_cpu <= ~r_clk_cpu; end end +initial begin + #275000 $finish(); +end + initial begin $dumpfile("sim_top.vcd"); $dumpvars(0,sim_top); diff --git a/hw/efinix_fpga/src/sdram_adapter.sv b/hw/efinix_fpga/src/sdram_adapter.sv index 9b0b7c0..deeccd9 100644 --- a/hw/efinix_fpga/src/sdram_adapter.sv +++ b/hw/efinix_fpga/src/sdram_adapter.sv @@ -70,7 +70,7 @@ assign o_sdr_DQM = w_sdr_DQM[0+:2]; // But basically if we are in access, and cpuclk goes low, go back to wait. // If something actually happened, we would be in one of the read/write states. -enum bit [1:0] {ACCESS, READ_WAIT, WRITE_WAIT, WAIT} state, next_state; +enum bit [2:0] {ACCESS, PRE_READ, READ_WAIT, PRE_WRITE, WRITE_WAIT, WAIT} state, next_state; logic w_read, w_write, w_last; logic [23:0] w_addr, r_addr; @@ -86,21 +86,6 @@ logic [31:0] r_write_data; logic [1:0] counter, next_counter; -always @(posedge i_sysclk) begin - if (i_arst) begin - state <= WAIT; - counter <= '0; - end else begin - state <= next_state; - counter <= next_counter; - r_write_data <= w_data_i; - r_addr <= w_addr; - r_dm <= w_dm; - end - - if (w_data_valid) - o_data <= _data; -end logic r_wait; logic _r_wait; @@ -126,6 +111,20 @@ always @(posedge i_sysclk or posedge i_arst) begin end end end + + if (i_arst) begin + state <= WAIT; + counter <= '0; + end else begin + state <= next_state; + counter <= next_counter; + r_write_data <= w_data_i; + r_addr <= w_addr; + r_dm <= w_dm; + end + + if (w_data_valid) + o_data <= _data; end //because of timing issues, We really need to trigger @@ -178,26 +177,29 @@ always_comb begin ACCESS: begin // only do something if selected if (i_cs) begin - w_addr = {{i_addr[24:2]}, {1'b0}};; // divide by 2, set last bit to 0 + w_addr = {{i_addr[24:2]}, {1'b0}}; // divide by 2, set last bit to 0 if (i_rwb) begin //read - w_read = '1; - w_last = '1; - // dm is not needed for reads? - if (w_rd_ack) next_state = READ_WAIT; + next_state = PRE_READ; end else begin //write w_data_i = i_data << (8*i_addr[1:0]); - //w_data_i = {4{i_data}}; //does anything get through? w_dm = ~(4'b1 << i_addr[1:0]); - if (~i_cpuclk) begin - w_write = '1; - w_last = '1; - next_state = WRITE_WAIT; - end + next_state = PRE_WRITE; end end end + PRE_WRITE: begin + w_data_i = r_write_data; + w_dm = r_dm; + //w_data_i = {4{i_data}}; //does anything get through? + if (~i_cpuclk) begin + w_write = '1; + w_last = '1; + next_state = WRITE_WAIT; + end + end + WRITE_WAIT: begin // stay in this state until write is acknowledged. w_write = '1; @@ -207,6 +209,13 @@ always_comb begin w_addr = r_addr; if (w_wr_ack) next_state = WAIT; end + + PRE_READ: begin + w_read = '1; + w_last = '1; + // dm is not needed for reads? + if (w_rd_ack) next_state = READ_WAIT; + end READ_WAIT: begin if (w_rd_valid) begin From 32f6c0f8d99c31180b00ebd7d2a7c429115ddff3 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 15 Oct 2023 13:30:09 -0700 Subject: [PATCH 54/57] Add jsr test --- hw/efinix_fpga/simulation/src/sim_top.sv | 6 ++-- sw/Makefile | 4 +-- sw/test_code/jsr_test/Makefile | 39 ++++++++++++++++++++++++ sw/test_code/jsr_test/link.ld | 35 +++++++++++++++++++++ sw/test_code/jsr_test/main.s | 23 ++++++++++++++ sw/test_code/jsr_test/vectors.s | 14 +++++++++ 6 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 sw/test_code/jsr_test/Makefile create mode 100644 sw/test_code/jsr_test/link.ld create mode 100644 sw/test_code/jsr_test/main.s create mode 100644 sw/test_code/jsr_test/vectors.s diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv index 98053fb..a01f70c 100644 --- a/hw/efinix_fpga/simulation/src/sim_top.sv +++ b/hw/efinix_fpga/simulation/src/sim_top.sv @@ -38,9 +38,9 @@ initial begin end end -initial begin - #275000 $finish(); -end +// initial begin +// #275000 $finish(); +// end initial begin $dumpfile("sim_top.vcd"); diff --git a/sw/Makefile b/sw/Makefile index a47ed42..ad99e40 100644 --- a/sw/Makefile +++ b/sw/Makefile @@ -17,6 +17,6 @@ kernel: clean: - @$(MAKE) -C bootloader --no-print-directory $@ + @$(MAKE) -C bios --no-print-directory $@ @$(MAKE) -C kernel --no-print-directory $@ - @$(MAKE) -C cc65 --no-print-directory $@ \ No newline at end of file + @$(MAKE) -C cc65 --no-print-directory $@ diff --git a/sw/test_code/jsr_test/Makefile b/sw/test_code/jsr_test/Makefile new file mode 100644 index 0000000..262a351 --- /dev/null +++ b/sw/test_code/jsr_test/Makefile @@ -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=jsr_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 + diff --git a/sw/test_code/jsr_test/link.ld b/sw/test_code/jsr_test/link.ld new file mode 100644 index 0000000..66a42fe --- /dev/null +++ b/sw/test_code/jsr_test/link.ld @@ -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 +} diff --git a/sw/test_code/jsr_test/main.s b/sw/test_code/jsr_test/main.s new file mode 100644 index 0000000..4c74c59 --- /dev/null +++ b/sw/test_code/jsr_test/main.s @@ -0,0 +1,23 @@ +.export _init, _nmi_int, _irq_int + +.code + +_nmi_int: +_irq_int: + +_init: + ldx #$ff + txs + lda #$00 + jsr subroutine + sta $00 +@1: bra @1 + +subroutine: + inc + jsr suborutine2 + rts + +suborutine2: + inc + rts \ No newline at end of file diff --git a/sw/test_code/jsr_test/vectors.s b/sw/test_code/jsr_test/vectors.s new file mode 100644 index 0000000..81ae6e0 --- /dev/null +++ b/sw/test_code/jsr_test/vectors.s @@ -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 \ No newline at end of file From e0e20d7fb40344cfbfe934052dfeed92df51db18 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 15 Oct 2023 13:37:13 -0700 Subject: [PATCH 55/57] Add indirect test --- sw/test_code/indirect_test/Makefile | 39 ++++++++++++++++++++++++++++ sw/test_code/indirect_test/link.ld | 35 +++++++++++++++++++++++++ sw/test_code/indirect_test/main.s | 20 ++++++++++++++ sw/test_code/indirect_test/vectors.s | 14 ++++++++++ 4 files changed, 108 insertions(+) create mode 100644 sw/test_code/indirect_test/Makefile create mode 100644 sw/test_code/indirect_test/link.ld create mode 100644 sw/test_code/indirect_test/main.s create mode 100644 sw/test_code/indirect_test/vectors.s diff --git a/sw/test_code/indirect_test/Makefile b/sw/test_code/indirect_test/Makefile new file mode 100644 index 0000000..5fbaadc --- /dev/null +++ b/sw/test_code/indirect_test/Makefile @@ -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=indirect_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 + diff --git a/sw/test_code/indirect_test/link.ld b/sw/test_code/indirect_test/link.ld new file mode 100644 index 0000000..66a42fe --- /dev/null +++ b/sw/test_code/indirect_test/link.ld @@ -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 +} diff --git a/sw/test_code/indirect_test/main.s b/sw/test_code/indirect_test/main.s new file mode 100644 index 0000000..65cf841 --- /dev/null +++ b/sw/test_code/indirect_test/main.s @@ -0,0 +1,20 @@ +.export _init, _nmi_int, _irq_int + +.code + +_nmi_int: +_irq_int: + +_init: + ldx #$ff + txs + + lda #$aa + sta $01 + lda #$bb + sta $00 + ldy #$1 + lda #$cc + sta ($00),y + +@end: bra @end \ No newline at end of file diff --git a/sw/test_code/indirect_test/vectors.s b/sw/test_code/indirect_test/vectors.s new file mode 100644 index 0000000..81ae6e0 --- /dev/null +++ b/sw/test_code/indirect_test/vectors.s @@ -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 \ No newline at end of file From 362c9f140fc625b9fe213b275fe92e6f350cbc54 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 15 Oct 2023 13:52:55 -0700 Subject: [PATCH 56/57] Fix synthesis issue --- hw/efinix_fpga/src/sdram_adapter.sv | 12 +- hw/efinix_fpga/super6502.xml | 167 ++++++++++++++-------------- 2 files changed, 93 insertions(+), 86 deletions(-) diff --git a/hw/efinix_fpga/src/sdram_adapter.sv b/hw/efinix_fpga/src/sdram_adapter.sv index deeccd9..c3c7822 100644 --- a/hw/efinix_fpga/src/sdram_adapter.sv +++ b/hw/efinix_fpga/src/sdram_adapter.sv @@ -86,6 +86,7 @@ logic [31:0] r_write_data; logic [1:0] counter, next_counter; +logic [7:0] o_data_next; logic r_wait; logic _r_wait; @@ -122,9 +123,8 @@ always @(posedge i_sysclk or posedge i_arst) begin r_addr <= w_addr; r_dm <= w_dm; end - - if (w_data_valid) - o_data <= _data; + + o_data <= o_data_next; end //because of timing issues, We really need to trigger @@ -167,6 +167,12 @@ always_comb begin w_data_i = '0; w_data_valid = '0; _data = 0; + + if (w_data_valid) begin + o_data_next = _data; + end else begin + o_data_next = o_data; + end unique case (state) WAIT: begin diff --git a/hw/efinix_fpga/super6502.xml b/hw/efinix_fpga/super6502.xml index 1431efd..55c88b1 100644 --- a/hw/efinix_fpga/super6502.xml +++ b/hw/efinix_fpga/super6502.xml @@ -1,105 +1,106 @@ - + + - - - + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - + + - - + + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + - \ No newline at end of file + From e768b245bd02d066a410028fd82382eccf984062 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 15 Oct 2023 18:24:19 -0700 Subject: [PATCH 57/57] rework state machine --- hw/efinix_fpga/src/sdram_adapter.sv | 52 +++++++++++++++++------------ 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/hw/efinix_fpga/src/sdram_adapter.sv b/hw/efinix_fpga/src/sdram_adapter.sv index c3c7822..be3c816 100644 --- a/hw/efinix_fpga/src/sdram_adapter.sv +++ b/hw/efinix_fpga/src/sdram_adapter.sv @@ -73,7 +73,8 @@ assign o_sdr_DQM = w_sdr_DQM[0+:2]; enum bit [2:0] {ACCESS, PRE_READ, READ_WAIT, PRE_WRITE, WRITE_WAIT, WAIT} state, next_state; logic w_read, w_write, w_last; -logic [23:0] w_addr, r_addr; +logic [23:0] w_read_addr, w_write_addr; +logic [23:0] r_read_addr, r_write_addr; logic [31:0] w_data_i, w_data_o; logic [3:0] w_dm, r_dm; @@ -88,9 +89,13 @@ logic [1:0] counter, next_counter; logic [7:0] o_data_next; +logic [23:0] addr_mux_out; + +logic slow_mem; + logic r_wait; logic _r_wait; -assign o_wait = r_wait & i_cs; +assign o_wait = (r_wait | slow_mem) & i_cs; // we need to assert rdy low until a falling edge if a reset happens @@ -120,7 +125,8 @@ always @(posedge i_sysclk or posedge i_arst) begin state <= next_state; counter <= next_counter; r_write_data <= w_data_i; - r_addr <= w_addr; + r_read_addr <= w_read_addr; + r_write_addr <= w_write_addr; r_dm <= w_dm; end @@ -156,10 +162,12 @@ end always_comb begin + slow_mem = '0; next_state = state; next_counter = counter; - w_addr = '0; + w_read_addr = '0; + w_write_addr = '0; w_dm = '0; w_read = '0; w_write = '0; @@ -167,24 +175,19 @@ always_comb begin w_data_i = '0; w_data_valid = '0; _data = 0; - - if (w_data_valid) begin - o_data_next = _data; - end else begin - o_data_next = o_data; - end unique case (state) WAIT: begin - if (i_cs & i_cpuclk) + if (i_cs & ~i_cpuclk) next_state = ACCESS; end ACCESS: begin // only do something if selected if (i_cs) begin - w_addr = {{i_addr[24:2]}, {1'b0}}; // divide by 2, set last bit to 0 - + w_read_addr = {{i_addr[24:2]}, {1'b0}}; // divide by 2, set last bit to 0 + w_write_addr = {{i_addr[24:2]}, {1'b0}}; // divide by 2, set last bit to 0 + addr_mux_out = w_read_addr; if (i_rwb) begin //read next_state = PRE_READ; end else begin //write @@ -197,6 +200,8 @@ always_comb begin PRE_WRITE: begin w_data_i = r_write_data; + w_write_addr = r_write_addr; + addr_mux_out = w_write_addr; w_dm = r_dm; //w_data_i = {4{i_data}}; //does anything get through? if (~i_cpuclk) begin @@ -208,43 +213,46 @@ always_comb begin WRITE_WAIT: begin // stay in this state until write is acknowledged. + w_write_addr = r_write_addr; + addr_mux_out = w_write_addr; w_write = '1; w_last = '1; w_data_i = r_write_data; w_dm = r_dm; - w_addr = r_addr; if (w_wr_ack) next_state = WAIT; end PRE_READ: begin + w_read_addr = r_read_addr; + addr_mux_out = w_read_addr; w_read = '1; w_last = '1; + slow_mem = '1; // dm is not needed for reads? if (w_rd_ack) next_state = READ_WAIT; end READ_WAIT: begin + w_read_addr = r_read_addr; + addr_mux_out = w_read_addr; + slow_mem = '1; if (w_rd_valid) begin w_data_valid = '1; _data = w_data_o[8*i_addr[1:0]+:8]; end // you must wait until the next cycle! - if (~i_cpuclk) begin + if (w_data_valid) begin next_state = WAIT; end end endcase -end -//this seems scuffed -logic [23:0] addr_mux_out; -always_comb begin - if (state == ACCESS) begin - addr_mux_out = w_addr; + if (w_data_valid) begin + o_data_next = _data; end else begin - addr_mux_out = r_addr; + o_data_next = o_data; end end