diff --git a/apple1_syn.prd b/apple1_syn.prd deleted file mode 100644 index 181fa84..0000000 --- a/apple1_syn.prd +++ /dev/null @@ -1,13 +0,0 @@ -#-- Synopsys, Inc. -#-- Version L-2016.09L+ice40 -#-- Project file C:\Users\Alan\Desktop\projects\apple1\apple1_syn.prd -#-- Written on Thu Jan 04 21:48:56 2018 - -# -### Watch Implementation type ### -# -watch_impl -all -# -### Watch Implementation properties ### -# -watch_prop -clear diff --git a/apple1_syn.prj b/apple1_syn.prj deleted file mode 100644 index 0012d3b..0000000 --- a/apple1_syn.prj +++ /dev/null @@ -1,76 +0,0 @@ -#-- Synopsys, Inc. -#-- Version L-2016.09L+ice40 -#-- Project file C:\Users\Alan\Desktop\projects\apple1\apple1_syn.prj -#-- Written on Mon Jan 01 00:45:12 2018 - - -#project files - - - -add_file -verilog -lib work "rtl/apple1_top.v" -add_file -verilog -lib work "rtl/chip_6502.v" -add_file -verilog -lib work "rtl/chip_6502_mux.v" -add_file -verilog -lib work "rtl/led_and_key.v" -add_file -verilog -lib work "rtl/tm1638.v" -add_file -verilog -lib work "rtl/uart.v" -#implementation: "apple1_Implmnt" -impl -add apple1_Implmnt -type fpga - -# -#implementation attributes - -set_option -vlog_std v2001 -set_option -project_relative_includes 1 - -#device options -set_option -technology SBTiCE40 -set_option -part iCE40HX8K -set_option -package CT256 -set_option -speed_grade -set_option -part_companion "" - -#compilation/mapping options -set_option -top_module "top" - -# hdl_compiler_options -set_option -distributed_compile 0 - -# mapper_without_write_options -set_option -frequency auto -set_option -srs_instrumentation 1 - -# mapper_options -set_option -write_verilog 0 -set_option -write_vhdl 0 - -# Lattice iCE40 -set_option -maxfan 10000 -set_option -rw_check_on_ram 0 -set_option -disable_io_insertion 0 -set_option -pipe 1 -set_option -retiming 0 -set_option -update_models_cp 0 -set_option -fix_gated_and_generated_clocks 1 -set_option -run_prop_extract 1 - -# NFilter -set_option -no_sequential_opt 0 - -# sequential_optimization_options -set_option -symbolic_fsm_compiler 1 - -# Compiler Options -set_option -compiler_compatible 0 -set_option -resource_sharing 1 - -# Compiler Options -set_option -auto_infer_blackbox 0 - -#automatic place and route (vendor) options -set_option -write_apr_constraint 1 - -#set result format/file last -project -result_file "apple1_Implmnt/apple1.edf" -impl -active apple1_Implmnt -project -run synthesis -clean diff --git a/apple1_sbt.project b/boards/ice40hx8k/appleone/appleone_sbt.project similarity index 72% rename from apple1_sbt.project rename to boards/ice40hx8k/appleone/appleone_sbt.project index 7b83ce5..3c5947b 100644 --- a/apple1_sbt.project +++ b/boards/ice40hx8k/appleone/appleone_sbt.project @@ -1,31 +1,31 @@ [Project] ProjectVersion=2.0 Version=Lattice Semiconductor Corporation iCEcube - Release: 2017.08.27940 - Build Date: Sep 11 2017 17:40:01 -ProjectName=apple1 +ProjectName=appleone Vendor=SiliconBlue Synthesis=synplify -ProjectVFiles=rtl/apple1_top.v,rtl/chip_6502.v,rtl/chip_6502_mux.v,rtl/led_and_key.v,rtl/tm1638.v,rtl/uart.v -ProjectCFiles= -CurImplementation=apple1_Implmnt -Implementations=apple1_Implmnt +ProjectVFiles=../../../rtl/apple1_top.v=work,../../../rtl/boards/ice40hx8k/clocks.v=work,../../../rtl/boards/ice40hx8k/clock_pll.v=work,../../../rtl/cpu/ALU.v=work,../../../rtl/cpu/cpu.v=work,../../../rtl/rom_wozmon.v,../../../rtl/uart/uart.v,../../../rtl/ram.v +ProjectCFiles=appleone_syn.sdc +CurImplementation=appleone_Implmnt +Implementations=appleone_Implmnt StartFromSynthesis=yes IPGeneration=false -[apple1_Implmnt] +[appleone_Implmnt] DeviceFamily=iCE40 Device=HX8K DevicePackage=CT256 DevicePower= -NetlistFile=apple1_Implmnt/apple1.edf +NetlistFile=appleone_Implmnt/appleone.edf AdditionalEDIFFile= IPEDIFFile= -DesignLib= -DesignView= -DesignCell= -SynthesisSDCFile=apple1_Implmnt/apple1.scf +DesignLib=appleone_Implmnt/sbt/netlist/oadb-top +DesignView=_rt +DesignCell=top +SynthesisSDCFile=appleone_Implmnt/appleone.scf UserPinConstraintFile= UserSDCFile= -PhysicalConstraintFile=ice40hx8k.pcf +PhysicalConstraintFile=../../../ice40hx8k.pcf BackendImplPathName= Devicevoltage=1.14 DevicevoltagePerformance=+/-5%(datasheet default) @@ -84,5 +84,5 @@ BitmapSetSecurity=no BitmapSetNoUsedIONoPullup=no FloorPlannerShowFanInNets=yes FloorPlannerShowFanOutNets=yes -HookTo3rdPartyTextEditor=no +HookTo3rdPartyTextEditor= diff --git a/boards/ice40hx8k/appleone/appleone_syn.prj b/boards/ice40hx8k/appleone/appleone_syn.prj new file mode 100644 index 0000000..d8f2d71 --- /dev/null +++ b/boards/ice40hx8k/appleone/appleone_syn.prj @@ -0,0 +1,64 @@ +#-- Synopsys, Inc. +#-- Project file C:\Users\Alan\Documents\GitHub\apple-one\boards\ice40hx8k\appleone\appleone_syn.prj +#project files + +add_file -verilog -lib work "../../../rtl/apple1_top.v" +add_file -verilog -lib work "../../../rtl/boards/ice40hx8k/clocks.v" +add_file -verilog -lib work "../../../rtl/boards/ice40hx8k/clock_pll.v" +add_file -verilog -lib work "../../../rtl/cpu/ALU.v" +add_file -verilog -lib work "../../../rtl/cpu/cpu.v" +add_file -verilog -lib work "../../../rtl/rom_wozmon.v" +add_file -verilog -lib work "../../../rtl/uart/uart.v" +add_file -verilog -lib work "../../../rtl/ram.v" +add_file -constraint -lib work "appleone_syn.sdc" +#implementation: "appleone_Implmnt" +impl -add appleone_Implmnt -type fpga + +#implementation attributes +set_option -vlog_std v2001 +set_option -project_relative_includes 1 + +#device options +set_option -technology SBTiCE40 +set_option -part iCE40HX8K +set_option -package CT256 +set_option -speed_grade +set_option -part_companion "" + +#compilation/mapping options + +# mapper_options +set_option -frequency auto +set_option -write_verilog 0 +set_option -write_vhdl 0 + +# Silicon Blue iCE40 +set_option -maxfan 10000 +set_option -disable_io_insertion 0 +set_option -pipe 1 +set_option -retiming 0 +set_option -update_models_cp 0 +set_option -fixgatedclocks 2 +set_option -fixgeneratedclocks 0 + +# NFilter +set_option -popfeed 0 +set_option -constprop 0 +set_option -createhierarchy 0 + +# sequential_optimization_options +set_option -symbolic_fsm_compiler 1 + +# Compiler Options +set_option -compiler_compatible 0 +set_option -resource_sharing 1 + +#automatic place and route (vendor) options +set_option -write_apr_constraint 1 + +#set result format/file last +project -result_format "edif" +project -result_file ./appleone_Implmnt/appleone.edf +project -log_file "./appleone_Implmnt/appleone.srr" +impl -active appleone_Implmnt +project -run synthesis -clean diff --git a/boards/ice40hx8k/appleone/appleone_syn.sdc b/boards/ice40hx8k/appleone/appleone_syn.sdc new file mode 100644 index 0000000..6d903db --- /dev/null +++ b/boards/ice40hx8k/appleone/appleone_syn.sdc @@ -0,0 +1,13 @@ +# ############################################################################## + +# iCEcube SDC + +# Version: 2016.02.27810 + +# File Generated: Jan 25 2018 13:49:15 + +# ############################################################################## + +####---- CreateClock list ----1 +create_clock -period 83.30 -name {clk} [get_ports {clk}] + diff --git a/rtl/apple1_top.v b/rtl/apple1_top.v index 6765b75..fb2d3f2 100644 --- a/rtl/apple1_top.v +++ b/rtl/apple1_top.v @@ -1,4 +1,4 @@ -`define LED_KEYS +`define ICE40 module top( input clk, @@ -7,247 +7,182 @@ module top( output uart_tx, output uart_cts, - `ifdef LED_KEYS - output tm_cs, - output tm_clk, - inout tm_dio, - `endif - - output reg [7:0] led + output [7:0] led, + output [7:0] ledx ); + ////////////////////////////////////////////////////////////////////////// + // Registers and Wires - wire clk_phi; - wire res, rw, irq, nmi; - wire [15:0] ab; - wire [7:0] dbo; - reg [7:0] dbi; + reg [15:0] ab; + wire [7:0] dbi; + reg [7:0] dbo; + reg we; ////////////////////////////////////////////////////////////////////////// - // USB UART - - wire received, is_receiving, rx_error, is_transmitting, transmit; - reg [6:0] tx_byte; - wire [7:0] rx_byte; + // Clocks + wire clk25; + wire cpu_clken; - uart #(.CLOCK_DIVIDE( 625 )) my_uart ( - clk, // master clock for this component - ~res, // synchronous reset line (resets if high) - uart_rx, // receive data on this line - uart_tx, // transmit data on this line - transmit, // signal to indicate that the UART should start a transmission - {1'b0, tx_byte}, // 8-bit bus with byte to be transmitted when transmit is raised high - received, // output flag raised high for one cycle of clk when a byte is received - rx_byte, // byte which has just been received when received is raise - is_receiving, // indicates that we are currently receiving data on the rx lin - is_transmitting, // indicates that we are currently sending data on the tx line - rx_error // rx packet corrupt - ); - - // sync the TX latch to the clk domain - reg apple_tx; - assign transmit = apple_tx; - - // sync the RX flag, using flag and ack - reg [6:0] apple_rx_buf; - reg apple_rx_ack; - reg apple_rx_flag; - - always @(posedge clk) - begin - if (received && !apple_rx_flag && !apple_rx_ack) begin - apple_rx_flag <= 1; - apple_rx_buf <= rx_byte[6:0]; - end - - if (apple_rx_flag && apple_rx_ack) - apple_rx_flag <= 0; - end - - // implement basic hardware flow control so 6502 can catch up - assign uart_cts = is_receiving || apple_rx_flag; - - ////////////////////////////////////////////////////////////////////////// - // TM1638 Display - - `ifdef LED_KEYS - reg [3:0] display; - reg [7:0] digits[7:0]; - reg [7:0] leds; - wire [7:0] keys; - - ledAndKey my_led_and_keys ( - .clk (clk_phi), - .rst (~res), - .display (display), - .digit1 (digits[0]), - .digit2 (digits[1]), - .digit3 (digits[2]), - .digit4 (digits[3]), - .digit5 (digits[4]), - .digit6 (digits[5]), - .digit7 (digits[6]), - .digit8 (digits[7]), - .leds (leds), - .keys (keys), - .tm_cs (tm_cs), - .tm_clk (tm_clk), - .tm_dio (tm_dio) + `ifdef ICE40 + clocks my_clocks( + .clk(clk), + .clk25(clk25), + .cpu_clken(cpu_clken) ); `endif ////////////////////////////////////////////////////////////////////////// - // 6502 reset - - reg [7:0] start; - always @(posedge clk) - if (~start[7]) start <= start + 1; + // Reset + wire reset; + reg hard_reset; + reg [5:0] reset_cnt; + wire pwr_up_reset = &reset_cnt; - assign res = start[7]; + always @(posedge clk25) + begin + if (cpu_clken) + begin + if (!pwr_up_reset) + reset_cnt <= reset_cnt + 1; - ////////////////////////////////////////////////////////////////////////// - // 6502 phi0 clock + hard_reset <= pwr_up_reset; + end + end - reg [3:0] div; - always @(posedge clk) - div <= div + 1; - - SB_GB bg_phi ( - .USER_SIGNAL_TO_GLOBAL_BUFFER(div[3]), - .GLOBAL_BUFFER_OUTPUT(clk_phi) - ); + assign reset = ~hard_reset; ////////////////////////////////////////////////////////////////////////// // 6502 + wire [7:0] dbo_c; + wire [15:0] ab_c; + wire we_c; + reg [7:0] dbi_c; - chip_6502 chip_6502 ( - .clk (clk), - .phi (clk_phi), - .res (res && ~keys[0]), - .so (1'b0), - .rdy (1'b1), - .nmi (nmi), - .irq (irq), - .rw (rw), - .dbi (dbi), - .dbo (dbo), - .ab (ab) + cpu my_cpu ( + .clk (clk25), + .reset (reset), + .AB (ab_c), + .DI (dbi_c), + .DO (dbo_c), + .WE (we_c), + .IRQ (1'b0), + .NMI (1'b0), + .RDY (cpu_clken) ); - ////////////////////////////////////////////////////////////////////////// - // I/O locations - - localparam UART_RX = 16'hD010; // PIA.A register on Apple 1 - RX byte - localparam UART_RXCR = 16'hD011; // PIA.A register on Apple 1 - RX control - localparam UART_TX = 16'hD012; // PIA.B register on Apple 1 - TX byte - localparam LED_KEYS = 16'hD020; // Start address of the Led&Keys module - localparam LED = 16'hD000; // Breakout board LEDs - - ////////////////////////////////////////////////////////////////////////// - // RAM and ROM - - reg [7:0] ram[0:8191] /* synthesis syn_ramstyle = "block_ram" */; - reg [7:0] rom[0:255] /* synthesis syn_ramstyle = "block_ram" */; - reg [7:0] basic[0:4095] /* synthesis syn_ramstyle = "block_ram" */; - - initial begin - $readmemh("../roms/ram.hex", ram, 0, 8191); - $readmemh("../roms/rom.hex", rom, 0, 255); - $readmemh("../roms/basic.hex", basic, 0, 4095); - end - - always @(posedge clk_phi) + always @(posedge clk25) begin - // clear the UART RX ack if set - if (apple_rx_ack) - apple_rx_ack <= 0; - - // clear the UART TX latch if set - if (apple_tx) - apple_tx <= 0; - - if (res) + if (cpu_clken) begin - case(ab) - // UART TX control and TX register - UART_TX: - begin - if (rw) - dbi <= {is_transmitting, 7'd0}; - else - begin - // Apple 1 terminal only uses 7 bits, MSB indicates - // terminal has ack'd RX - tx_byte <= dbo[6:0]; - apple_tx <= 1; - end - end - - // UART RX control register - UART_RXCR: - begin - if (rw) - dbi <= {apple_rx_flag, 7'b0}; - end - - // UART RX register - UART_RX: - begin - if (rw) - begin - // Apple 1 terminal only uses 7 bits, MSB tied high - // Wozmon checks for MSB being high - dbi <= apple_rx_flag ? {1'b1, apple_rx_buf} : 8'b0; - apple_rx_ack <= 1; - end - end - - `ifdef LED_KEYS - // LED&KEYS registers - LED_KEYS: if (rw) dbi <= {4'b0, display}; else display <= dbo[3:0]; - LED_KEYS + 1: if (rw) dbi <= digits[0]; else digits[0] <= dbo; - LED_KEYS + 2: if (rw) dbi <= digits[1]; else digits[1] <= dbo; - LED_KEYS + 3: if (rw) dbi <= digits[2]; else digits[2] <= dbo; - LED_KEYS + 4: if (rw) dbi <= digits[3]; else digits[3] <= dbo; - LED_KEYS + 5: if (rw) dbi <= digits[4]; else digits[4] <= dbo; - LED_KEYS + 6: if (rw) dbi <= digits[5]; else digits[5] <= dbo; - LED_KEYS + 7: if (rw) dbi <= digits[6]; else digits[6] <= dbo; - LED_KEYS + 8: if (rw) dbi <= digits[7]; else digits[7] <= dbo; - LED_KEYS + 9: if (rw) dbi <= leds; else leds <= dbo; - LED_KEYS + 10: if (rw) dbi <= keys; - `endif - - // breakout board LED registers - LED: if (rw) dbi <= led; else led <= dbo; - - default: - begin - if (ab[15:12] == 4'b0000 || ab[15:12] == 4'b0001) - begin - // 0x0000 -> 0x1FFF - RAM - dbi <= ram[ab[12:0]]; - if (~rw) ram[ab[12:0]] <= dbo; - end - else if (ab[15:12] == 4'b1110) - begin - // 0xE000 -> 0xEFFF - BASIC - dbi <= basic[ab[11:0]]; - end - else if (ab[15:8] == 8'b11111111) - begin - // 0xFF00 -> 0xFFFF - ROM - dbi <= rom[ab[7:0]]; - end - else - // unknown address return zero - dbi <= 8'h0; - end - - endcase + ab <= ab_c; + dbo <= dbo_c; + dbi_c <= dbi; + we <= we_c; end end - // set irq and nmi high. for later use - assign irq = 1; - assign nmi = 1; + ////////////////////////////////////////////////////////////////////////// + // RAM and ROM + wire ram_cs = (ab[15:13] == 3'b000); // 0x0000 -> 0x1FFF + wire uart_cs = (ab[15:2] == 14'b11010000000100); // 0xD010 -> 0xD013 + wire basic_cs = (ab[15:12] == 4'b1110); // 0xE000 -> 0xEFFF + wire rom_cs = (ab[15:8] == 8'b11111111); // 0xFF00 -> 0xFFFF + + // RAM + wire [7:0] ram_dout; + ram my_ram ( + .clk(clk25), + .address(ab[12:0]), + .w_en(we & ram_cs), + .din(dbo), + .dout(ram_dout) + ); + + // WozMon ROM + wire [7:0] rom_dout; + rom_wozmon my_rom_wozmon ( + .clk(clk25), + .address(ab[7:0]), + .dout(rom_dout) + ); + + // UART + wire [7:0] uart_dout; + uart my_uart ( + .clk(clk25), + + .uart_rx(uart_rx), + .uart_tx(uart_tx), + .uart_cts(uart_cts), + + .enable(uart_cs & cpu_clken), + .address(ab[1:0]), + .w_en(we & uart_cs), + .din(dbo), + .dout(uart_dout), + .led(led) + ); + + // link up chip selected device to cpu input + assign dbi = ram_cs ? ram_dout : + rom_cs ? rom_dout : + uart_cs ? uart_dout : + 8'hFF; + + assign ledx = ab[7:0]; + +// always @(posedge clk25) +// begin +// if (cpu_clken) +// begin +// led <= ab[7:0]; +// ledx <= ~ab[15:8]; +// end +// end + +// reg [7:0] ram[0:8191] /* synthesis syn_ramstyle = "block_ram" */; +// reg [7:0] rom[0:255] /* synthesis syn_ramstyle = "block_ram" */; +// reg [7:0] basic[0:4095] /* synthesis syn_ramstyle = "block_ram" */; +// +// initial begin +// $readmemh("../roms/ram.hex", ram, 0, 8191); +// $readmemh("../roms/rom.hex", rom, 0, 255); +// $readmemh("../roms/basic.hex", basic, 0, 4095); +// end +// +// always @(posedge clk_25) +// begin +// if (phi_clk_en) +// begin +// if (res) +// begin +// case(ab) +// default: +// begin +// if (ab[15:12] == 4'b0000 || ab[15:12] == 4'b0001) +// begin +// // 0x0000 -> 0x1FFF - RAM +// dbi <= ram[ab[12:0]]; +// if (~rw) ram[ab[12:0]] <= dbo; +// end +// else if (ab[15:12] == 4'b1110) +// begin +// // 0xE000 -> 0xEFFF - BASIC +// dbi <= basic[ab[11:0]]; +// end +// else if (ab[15:8] == 8'b11111111) +// begin +// // 0xFF00 -> 0xFFFF - ROM +// dbi <= rom[ab[7:0]]; +// end +// else +// // unknown address return zero +// dbi <= 8'h0; +// end +// +// endcase +// end +// end +// end endmodule diff --git a/rtl/boards/ice40hx8k/clock_pll.v b/rtl/boards/ice40hx8k/clock_pll.v new file mode 100644 index 0000000..a937514 --- /dev/null +++ b/rtl/boards/ice40hx8k/clock_pll.v @@ -0,0 +1,38 @@ +module clock_pll(REFERENCECLK, + PLLOUTCORE, + PLLOUTGLOBAL, + RESET); + +input REFERENCECLK; +input RESET; /* To initialize the simulation properly, the RESET signal (Active Low) must be asserted at the beginning of the simulation */ +output PLLOUTCORE; +output PLLOUTGLOBAL; + +SB_PLL40_CORE clock_pll_inst(.REFERENCECLK(REFERENCECLK), + .PLLOUTCORE(PLLOUTCORE), + .PLLOUTGLOBAL(PLLOUTGLOBAL), + .EXTFEEDBACK(), + .DYNAMICDELAY(), + .RESETB(RESET), + .BYPASS(1'b0), + .LATCHINPUTVALUE(), + .LOCK(), + .SDI(), + .SDO(), + .SCLK()); + +//\\ Fin=12, Fout=25; +defparam clock_pll_inst.DIVR = 4'b0000; +defparam clock_pll_inst.DIVF = 7'b1000010; +defparam clock_pll_inst.DIVQ = 3'b101; +defparam clock_pll_inst.FILTER_RANGE = 3'b001; +defparam clock_pll_inst.FEEDBACK_PATH = "SIMPLE"; +defparam clock_pll_inst.DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED"; +defparam clock_pll_inst.FDA_FEEDBACK = 4'b0000; +defparam clock_pll_inst.DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED"; +defparam clock_pll_inst.FDA_RELATIVE = 4'b0000; +defparam clock_pll_inst.SHIFTREG_DIV_MODE = 2'b00; +defparam clock_pll_inst.PLLOUT_SELECT = "GENCLK"; +defparam clock_pll_inst.ENABLE_ICEGATE = 1'b0; + +endmodule diff --git a/rtl/boards/ice40hx8k/clock_pll_inst.v b/rtl/boards/ice40hx8k/clock_pll_inst.v new file mode 100644 index 0000000..d26da97 --- /dev/null +++ b/rtl/boards/ice40hx8k/clock_pll_inst.v @@ -0,0 +1,4 @@ +clock_pll clock_pll_inst(.REFERENCECLK(), + .PLLOUTCORE(), + .PLLOUTGLOBAL(), + .RESET()); diff --git a/rtl/boards/ice40hx8k/clock_pll_v.lpc b/rtl/boards/ice40hx8k/clock_pll_v.lpc new file mode 100644 index 0000000..d0d3340 --- /dev/null +++ b/rtl/boards/ice40hx8k/clock_pll_v.lpc @@ -0,0 +1,5 @@ +[General] +DeviceFamily=iCE40 + +[AdditionalDelay] +AdditionalDelayNo=true diff --git a/rtl/boards/ice40hx8k/clocks.v b/rtl/boards/ice40hx8k/clocks.v new file mode 100644 index 0000000..f9c5881 --- /dev/null +++ b/rtl/boards/ice40hx8k/clocks.v @@ -0,0 +1,34 @@ +module clocks ( + input clk, + output clk25, + + output reg cpu_clken +); + + // 12MHz up to 25MHz + clock_pll clock_pll_inst( + .REFERENCECLK(clk), + .PLLOUTCORE(), + .PLLOUTGLOBAL(clk25), + .RESET(1'b1) + ); + + reg [25:0] clk_div; + + always @(posedge clk25) + begin + if (clk_div == 12000000) + clk_div <= 0; + else + clk_div <= clk_div + 1; + + // 1MHz + cpu_clken <= (clk_div[25:0] == 0); + + // 2MHz + //cpu_clken <= (clk_div[4] == 0) & (clk_div[2:0] == 0); + + // 4MHz + //cpu_clken <= (clk_div[4] == 0) & (clk_div[1:0] == 0); + end +endmodule diff --git a/rtl/chip_6502.v b/rtl/chip_6502.v deleted file mode 100644 index 4c36885..0000000 --- a/rtl/chip_6502.v +++ /dev/null @@ -1,66 +0,0 @@ -`include "chip_6502_nodes.inc" - -module LOGIC ( - input [`NUM_NODES-1:0] i, - output [`NUM_NODES-1:0] o); - - `include "chip_6502_logic.inc" -endmodule - - -module chip_6502 ( - input clk, // FPGA clock - input phi, // 6502 clock - input res, - input so, - input rdy, - input nmi, - input irq, - input [7:0] dbi, - output [7:0] dbo, - output rw, - output sync, - output [15:0] ab); - - // Node states - wire [`NUM_NODES-1:0] no; - reg [`NUM_NODES-1:0] ni; - reg [`NUM_NODES-1:0] q = 0; - - LOGIC logic_00 (.i(ni), .o(no)); - - always @ (posedge clk) - q <= no; - - always @* begin - ni = q; - - ni[`NODE_vcc ] = 1'b1; - ni[`NODE_vss ] = 1'b0; - ni[`NODE_res ] = res; - ni[`NODE_clk0] = phi; - ni[`NODE_so ] = so; - ni[`NODE_rdy ] = rdy; - ni[`NODE_nmi ] = nmi; - ni[`NODE_irq ] = irq; - - {ni[`NODE_db7],ni[`NODE_db6],ni[`NODE_db5],ni[`NODE_db4], - ni[`NODE_db3],ni[`NODE_db2],ni[`NODE_db1],ni[`NODE_db0]} = dbi[7:0]; - end - - assign dbo[7:0] = { - no[`NODE_db7],no[`NODE_db6],no[`NODE_db5],no[`NODE_db4], - no[`NODE_db3],no[`NODE_db2],no[`NODE_db1],no[`NODE_db0] - }; - - assign ab[15:0] = { - no[`NODE_ab15], no[`NODE_ab14], no[`NODE_ab13], no[`NODE_ab12], - no[`NODE_ab11], no[`NODE_ab10], no[`NODE_ab9], no[`NODE_ab8], - no[`NODE_ab7], no[`NODE_ab6], no[`NODE_ab5], no[`NODE_ab4], - no[`NODE_ab3], no[`NODE_ab2], no[`NODE_ab1], no[`NODE_ab0] - }; - - assign rw = no[`NODE_rw]; - assign sync = no[`NODE_sync]; - -endmodule diff --git a/rtl/chip_6502_logic.inc b/rtl/chip_6502_logic.inc deleted file mode 100644 index 1aadd99..0000000 --- a/rtl/chip_6502_logic.inc +++ /dev/null @@ -1,872 +0,0 @@ -assign o[674] = i[192]|i[256]; -assign o[928] = i[1077]|i[829]; -assign o[522] = i[197]|i[403]; -assign o[1117] = i[1134]|i[717]; -assign o[876] = i[276]|i[697]; -assign o[1448] = ~i[636]|i[660]; -assign o[996] = ~i[310]|~i[119]; -assign o[1018] = i[893]|i[68]; -assign o[1688] = i[787]|i[673]; -assign o[1309] = i[1077]|i[1669]; -assign o[1228] = i[303]|i[1504]; -assign o[125] = i[1410]|i[809]|i[540]; -assign o[1081] = i[1055]|i[1337]|i[1355]; -assign o[925] = ~i[1675]|i[541]|~i[1609]; -assign o[544] = i[1609]|i[1675]|~i[541]|i[119]; -assign o[630] = i[0]|i[1210]|i[461]|i[677]; -assign o[664] = i[1620]|~i[310]|i[1050]|~i[1300]; -assign o[837] = i[310]|i[1675]|i[1536]|~i[541]|~i[1609]; -assign o[636] = ~i[1620]|~i[1575]|~i[1300]|i[927]|i[996]; -assign o[218] = i[309]|i[528]|i[932]|i[1589]|i[446]|i[1430]; -assign o[847] = i[1382]|i[712]|~i[1107]|i[1259]|i[857]|i[342]; -assign o[980] = i[1620]|i[1675]|~i[927]|~i[541]|i[1300]|~i[678]|i[996]; -assign o[1065] = i[1620]|i[1675]|i[1536]|~i[1300]|~i[541]|i[927]|i[996]; -assign o[889] = i[1620]|~i[1675]|i[1536]|~i[1300]|~i[541]|i[927]|i[996]; -assign o[1379] = i[1609]|~i[1675]|i[1536]|~i[927]|~i[541]|i[1300]|i[996]; -assign o[774] = i[1620]|i[1675]|i[1536]|~i[1300]|i[541]|i[927]|i[996]; -assign o[340] = i[1620]|i[1609]|~i[1675]|~i[1300]|i[541]|i[927]|i[996]; -assign o[1268] = i[1503]|i[493]|i[1473]|i[1108]|i[991]|i[1302]|i[892]|i[833]; -assign o[1586] = i[1620]|i[1609]|~i[1675]|i[1536]|~i[1300]|i[541]|i[119]|i[927]; -assign o[1219] = ~i[1620]|i[1609]|~i[378]|~i[1675]|~i[927]|~i[1300]|~i[541]|i[996]; -assign o[979] = ~i[24]&i[546]; -assign o[19] = ~(~i[660]|~i[559]); -assign o[36] = ~(~i[1341]|i[393]); -assign o[46] = ~(i[197]|~i[595]); -assign o[53] = ~(i[1675]|i[119]); -assign o[65] = ~(~i[1425]|i[308]); -assign o[80] = ~(i[1130]|i[267]); -assign o[160] = ~(i[781]|~i[366]); -assign o[169] = ~(i[1624]|i[366]); -assign o[174] = ~(~i[427]|i[1459]); -assign o[176] = ~(i[10]|i[660]); -assign o[180] = ~(i[197]|i[1716]); -assign o[188] = ~(i[1606]|~i[223]); -assign o[193] = ~(~i[1122]|i[701]); -assign o[200] = ~(~i[292]|i[919]); -assign o[204] = ~(~i[1620]|~i[1575]); -assign o[251] = ~(i[1035]|~i[1579]); -assign o[260] = ~(i[1205]|~i[1001]); -assign o[261] = ~(i[447]|i[461]); -assign o[264] = ~(i[1312]|i[1149]); -assign o[269] = ~(i[1241]|~i[336]); -assign o[275] = ~(i[773]|~i[664]); -assign o[295] = ~(i[425]|~i[1285]); -assign o[327] = ~(i[1226]|i[1569]); -assign o[334] = ~(i[1382]|i[1553]); -assign o[335] = ~(i[347]|i[925]); -assign o[378] = ~(~i[223]|i[18]); -assign o[385] = ~(i[604]|~i[857]); -assign o[410] = ~(i[1184]|~i[900]); -assign o[412] = ~(i[164]|i[560]); -assign o[425] = ~(i[155]|~i[841]); -assign o[467] = ~(i[134]|i[17]); -assign o[479] = ~(i[739]|~i[1336]); -assign o[506] = ~(i[192]|i[660]); -assign o[516] = ~(i[1691]|~i[681]); -assign o[540] = ~(i[1077]|i[369]); -assign o[550] = ~(i[384]|i[1228]); -assign o[553] = ~(i[781]|~i[1124]); -assign o[555] = ~(i[1525]|~i[590]); -assign o[595] = ~(i[354]|i[1168]); -assign o[637] = ~(i[1318]|i[1314]); -assign o[640] = ~(i[649]|~i[350]); -assign o[678] = ~(~i[223]|i[644]); -assign o[717] = ~(i[1132]|i[1036]); -assign o[720] = ~(i[197]|i[56]); -assign o[735] = ~(~i[1150]|i[36]); -assign o[743] = ~(i[523]|~i[49]); -assign o[753] = ~(i[1257]|i[811]); -assign o[773] = ~(~i[17]|i[273]); -assign o[781] = ~(i[197]|i[199]); -assign o[790] = ~(i[53]|i[691]); -assign o[809] = ~(i[1077]|i[361]); -assign o[810] = ~(~i[584]|i[293]); -assign o[811] = ~(~i[412]|~i[581]); -assign o[812] = ~(~i[17]|~i[24]); -assign o[813] = ~(i[653]|~i[24]); -assign o[817] = ~(i[1220]|~i[142]); -assign o[819] = ~(i[449]|i[596]); -assign o[824] = ~(i[487]|i[579]); -assign o[827] = ~(~i[717]|i[1350]); -assign o[860] = ~(~i[1023]|i[640]); -assign o[877] = ~(i[506]|i[933]); -assign o[879] = ~(i[197]|~i[1011]); -assign o[882] = ~(i[597]|i[1252]); -assign o[917] = ~(i[197]|~i[712]); -assign o[930] = ~(i[134]|i[1276]); -assign o[944] = ~(i[89]|i[759]); -assign o[959] = ~(i[430]|i[294]); -assign o[964] = ~(i[554]|i[1533]); -assign o[1044] = ~(~i[32]|i[812]); -assign o[1055] = ~(~i[660]|i[756]); -assign o[1069] = ~(~i[94]|i[1274]); -assign o[1087] = ~(i[1382]|i[717]); -assign o[1090] = ~(~i[1225]|i[157]); -assign o[1097] = ~(i[345]|~i[1188]); -assign o[1109] = ~(i[1464]|i[902]); -assign o[1115] = ~(i[1609]|i[620]); -assign o[1134] = ~(i[1465]|~i[698]); -assign o[1154] = ~(i[197]|i[959]); -assign o[1159] = ~(i[613]|~i[1287]); -assign o[1170] = ~(i[781]|~i[443]); -assign o[1179] = ~(~i[1425]|~i[599]); -assign o[1180] = ~(i[197]|i[554]); -assign o[1213] = ~(~i[205]|i[609]); -assign o[1217] = ~(i[1241]|~i[1314]); -assign o[1220] = ~(i[1632]|~i[477]); -assign o[1225] = ~(i[285]|i[1524]); -assign o[1241] = ~(~i[1318]|i[1398]); -assign o[1253] = ~(~i[655]|i[1542]); -assign o[1257] = ~(i[412]|~i[1565]); -assign o[1286] = ~(i[17]|i[930]); -assign o[1312] = ~(i[1693]|i[1291]); -assign o[1316] = ~(i[344]|~i[377]); -assign o[1342] = ~(i[310]|i[1536]); -assign o[1343] = ~(i[197]|i[152]); -assign o[1345] = ~(i[379]|~i[1139]); -assign o[1350] = ~(i[1382]|i[760]); -assign o[1374] = ~(i[562]|i[882]); -assign o[1380] = ~(i[819]|i[1154]); -assign o[1382] = ~(i[197]|~i[1452]); -assign o[1391] = ~(i[352]|i[750]); -assign o[1410] = ~(i[1077]|i[1690]); -assign o[1457] = ~(i[781]|~i[974]); -assign o[1465] = ~(i[197]|~i[370]); -assign o[1517] = ~(~i[1176]|i[559]); -assign o[1575] = ~(~i[223]|i[1360]); -assign o[1587] = ~(i[1077]|i[894]); -assign o[1610] = ~(i[640]|~i[681]); -assign o[1619] = ~(i[1448]|i[182]); -assign o[1622] = ~(i[1077]|i[758]); -assign o[1629] = ~(~i[166]|i[753]); -assign o[1671] = ~(i[1077]|i[955]); -assign o[1705] = ~(i[467]|i[630]); -assign o[10] = ~(i[467]|i[1721]|i[1211]); -assign o[14] = ~(~i[1395]|i[323]|i[671]); -assign o[58] = ~(i[927]|i[1620]|~i[678]); -assign o[134] = ~(i[1557]|i[259]|i[1052]); -assign o[187] = ~(i[197]|~i[717]|i[1131]); -assign o[191] = ~(i[347]|i[197]|i[790]); -assign o[258] = ~(i[1300]|~i[1575]|i[927]); -assign o[267] = ~(i[544]|i[785]|~i[1447]); -assign o[273] = ~(~i[1575]|i[1620]|i[791]); -assign o[279] = ~(~i[1104]|~i[338]|~i[1049]); -assign o[281] = ~(i[927]|i[1620]|~i[188]); -assign o[285] = ~(~i[1575]|~i[1620]|i[1300]); -assign o[307] = ~(i[541]|~i[32]|~i[1675]); -assign o[354] = ~(i[927]|i[1620]|~i[188]); -assign o[447] = ~(i[927]|i[1620]|~i[678]); -assign o[501] = ~(i[819]|~i[1395]|i[180]); -assign o[510] = ~(i[347]|i[1052]|~i[790]); -assign o[513] = ~(i[1646]|~i[338]|~i[384]); -assign o[546] = ~(~i[1675]|~i[541]|i[119]); -assign o[616] = ~(i[1482]|i[286]|i[665]); -assign o[677] = ~(i[791]|i[1620]|~i[678]); -assign o[691] = ~(~i[1675]|~i[541]|i[119]); -assign o[844] = ~(i[786]|i[985]|i[1664]); -assign o[1019] = ~(i[1622]|~i[1587]|i[1671]); -assign o[1215] = ~(i[1382]|i[1185]|~i[1713]); -assign o[1243] = ~(~i[541]|i[310]|~i[1533]); -assign o[1246] = ~(~i[541]|i[1675]|i[119]); -assign o[1275] = ~(i[832]|i[197]|i[1019]); -assign o[1293] = ~(i[541]|i[1675]|~i[627]); -assign o[1358] = ~(i[917]|i[1109]|i[245]); -assign o[1368] = ~(i[1374]|~i[1431]|~i[1032]); -assign o[1371] = ~(~i[69]|~i[541]|~i[1675]); -assign o[1433] = ~(~i[541]|i[1675]|~i[1625]); -assign o[1562] = ~(~i[1675]|i[541]|i[119]); -assign o[1614] = ~(i[1177]|i[1111]|i[1436]); -assign o[1712] = ~(i[1134]|i[264]|~i[717]); -assign o[145] = ~(~i[1675]|i[541]|i[310]|~i[1609]); -assign o[152] = ~(~i[272]|i[630]|~i[1219]|i[1575]); -assign o[219] = ~(~i[1575]|~i[927]|~i[1620]|i[1300]); -assign o[302] = ~(~i[1622]|~i[1587]|i[1671]|i[540]); -assign o[324] = ~(i[1675]|i[541]|i[1609]|i[119]); -assign o[384] = ~(i[946]|i[1228]|i[653]|~i[1455]); -assign o[388] = ~(i[425]|i[623]|i[516]|~i[841]); -assign o[570] = ~(~i[477]|i[1220]|i[142]|~i[1459]); -assign o[575] = ~(i[310]|i[1675]|i[1609]|i[1536]); -assign o[607] = ~(~i[927]|i[1300]|i[1620]|~i[678]); -assign o[620] = ~(i[307]|i[1433]|i[1371]|i[1293]); -assign o[822] = ~(i[310]|i[1675]|i[1609]|~i[1533]); -assign o[904] = ~(i[1300]|i[927]|~i[1620]|~i[678]); -assign o[1031] = ~(~i[927]|~i[541]|~i[678]|i[996]); -assign o[1057] = ~(~i[1575]|~i[927]|i[1620]|i[1300]); -assign o[1155] = ~(i[310]|i[1675]|i[1609]|~i[1533]); -assign o[1178] = ~(i[960]|i[614]|i[848]|i[1652]); -assign o[1185] = ~(i[729]|i[916]|i[197]|i[1137]); -assign o[1196] = ~(i[522]|i[1228]|~i[837]|~i[366]); -assign o[1385] = ~(~i[1620]|i[310]|~i[378]|~i[1300]); -assign o[1466] = ~(~i[1675]|~i[541]|i[1609]|i[119]); -assign o[1524] = ~(~i[1575]|i[310]|~i[1620]|~i[1300]); -assign o[1540] = ~(~i[1675]|i[541]|i[119]|~i[1609]); -assign o[1716] = ~(i[510]|i[653]|i[218]|i[660]); -assign o[60] = ~(i[310]|~i[1620]|i[927]|~i[1300]|~i[678]); -assign o[84] = ~(i[310]|~i[1575]|~i[927]|~i[1620]|~i[1300]); -assign o[104] = ~(~i[636]|~i[24]|i[1589]|i[275]|i[847]); -assign o[157] = ~(~i[927]|~i[1575]|~i[541]|~i[1300]|i[996]); -assign o[301] = ~(~i[1533]|i[310]|i[541]|i[1675]|~i[1609]); -assign o[342] = ~(i[310]|~i[1620]|i[927]|~i[1300]|~i[678]); -assign o[347] = ~(i[281]|i[219]|i[1385]|i[607]|i[904]); -assign o[403] = ~(i[1536]|~i[1675]|~i[541]|i[310]|~i[1609]); -assign o[461] = ~(i[310]|~i[1620]|i[927]|~i[1300]|~i[188]); -assign o[492] = ~(i[310]|~i[1620]|i[927]|~i[1300]|~i[188]); -assign o[660] = ~(i[927]|~i[1620]|~i[678]|~i[1300]|i[996]); -assign o[787] = ~(i[310]|i[1675]|i[1536]|i[1609]|i[541]); -assign o[791] = ~(~i[927]|i[1620]|~i[541]|~i[1300]|i[996]); -assign o[985] = ~(i[1536]|~i[1675]|i[541]|i[1609]|i[119]); -assign o[1050] = ~(~i[927]|i[1620]|~i[541]|~i[1300]|i[996]); -assign o[1130] = ~(~i[1219]|i[192]|i[1109]|i[653]|~i[666]); -assign o[1168] = ~(i[310]|~i[1620]|~i[378]|~i[1300]|i[927]); -assign o[1204] = ~(~i[1575]|~i[1620]|i[310]|~i[1300]|i[927]); -assign o[1210] = ~(i[310]|~i[1620]|~i[927]|~i[378]|~i[1300]); -assign o[1211] = ~(~i[636]|i[273]|~i[666]|~i[1219]|i[1286]); -assign o[1259] = ~(i[310]|~i[1620]|~i[927]|~i[1300]|~i[188]); -assign o[1294] = ~(i[1587]|i[1622]|i[1671]|~i[1410]|i[540]); -assign o[1334] = ~(~i[292]|~i[1670]|~i[1704]|~i[584]|~i[502]); -assign o[1337] = ~(i[1536]|~i[927]|i[541]|i[1675]|i[996]); -assign o[1355] = ~(i[1536]|i[310]|i[541]|i[1675]|~i[1609]); -assign o[1420] = ~(~i[1675]|i[310]|i[1536]|i[1609]|i[541]); -assign o[1428] = ~(i[310]|~i[1620]|~i[927]|~i[1300]|~i[678]); -assign o[1504] = ~(~i[1675]|i[310]|i[1536]|i[1609]|~i[541]); -assign o[1512] = ~(~i[1575]|i[1620]|i[310]|~i[1300]|i[927]); -assign o[1582] = ~(~i[927]|~i[1575]|~i[541]|~i[1300]|i[996]); -assign o[1601] = ~(~i[1675]|i[1300]|i[541]|~i[1609]|i[996]); -assign o[272] = ~(~i[17]|i[273]|~i[636]|i[660]|i[0]|~i[666]); -assign o[286] = ~(~i[1675]|i[1536]|~i[927]|i[541]|i[1609]|i[996]); -assign o[665] = ~(~i[1675]|i[1536]|i[1300]|i[541]|i[1609]|i[996]); -assign o[764] = ~(~i[927]|~i[541]|i[1675]|i[1300]|i[1620]|i[996]); -assign o[857] = ~(i[1675]|~i[927]|~i[1620]|~i[541]|~i[1300]|i[996]); -assign o[1052] = ~(~i[927]|~i[541]|i[1675]|i[1300]|i[1620]|i[996]); -assign o[1233] = ~(i[1536]|~i[927]|i[1675]|i[541]|~i[1609]|i[996]); -assign o[1324] = ~(~i[927]|~i[541]|i[1620]|~i[1533]|~i[1300]|i[119]); -assign o[1347] = ~(~i[636]|i[1396]|i[979]|i[550]|~i[666]|i[782]); -assign o[1352] = ~(i[653]|~i[24]|i[335]|i[352]|i[1642]|i[932]); -assign o[1396] = ~(i[1536]|~i[927]|i[1620]|~i[541]|~i[1300]|i[119]); -assign o[1464] = ~(i[370]|i[784]|i[271]|i[552]|i[1612]|i[1487]); -assign o[1520] = ~(i[1620]|~i[927]|i[1609]|~i[541]|~i[1300]|i[996]); -assign o[1557] = ~(~i[927]|~i[541]|~i[1620]|~i[1609]|~i[1300]|i[996]); -assign o[1658] = ~(i[1536]|~i[927]|i[1675]|i[541]|i[1609]|i[996]); -assign o[1710] = ~(~i[927]|~i[1533]|i[1675]|i[541]|~i[1620]|i[996]); -assign o[1721] = ~(i[1536]|i[927]|~i[1620]|~i[47]|~i[1300]|i[996]); -assign o[256] = ~(i[784]|i[0]|i[1478]|i[594]|i[188]|i[1210]|i[678]); -assign o[259] = ~(~i[1675]|~i[1620]|~i[927]|i[1609]|~i[541]|~i[1300]|i[996]); -assign o[303] = ~(i[1536]|~i[1675]|~i[927]|~i[541]|i[1300]|i[1609]|i[996]); -assign o[382] = ~(i[1536]|~i[927]|i[541]|i[1620]|~i[1609]|~i[1300]|i[996]); -assign o[446] = ~(i[1675]|~i[1620]|~i[927]|~i[378]|~i[541]|~i[1300]|i[996]); -assign o[552] = ~(i[1536]|~i[927]|~i[541]|i[1620]|~i[1609]|~i[1300]|i[996]); -assign o[594] = ~(i[1536]|~i[927]|~i[541]|i[1675]|i[1300]|i[1620]|i[996]); -assign o[804] = ~(~i[1675]|~i[927]|~i[541]|~i[1620]|~i[188]|~i[1300]|i[996]); -assign o[932] = ~(~i[927]|~i[1575]|~i[541]|i[1620]|~i[1609]|~i[1300]|i[996]); -assign o[950] = ~(~i[927]|~i[1533]|i[1300]|i[1675]|i[541]|i[1620]|i[996]); -assign o[1074] = ~(i[1536]|i[1675]|~i[927]|i[1620]|~i[541]|~i[1300]|i[119]); -assign o[1430] = ~(~i[927]|i[1620]|~i[541]|i[1609]|~i[678]|~i[1300]|i[996]); -assign o[1455] = ~(i[1420]|i[179]|i[131]|i[1324]|i[1243]|i[257]|i[822]); -assign o[1478] = ~(i[1536]|~i[927]|~i[541]|~i[1620]|~i[1609]|~i[1300]|i[996]); -assign o[1482] = ~(~i[927]|~i[1533]|i[541]|i[1620]|~i[1609]|~i[1300]|i[996]); -assign o[1487] = ~(~i[927]|i[1620]|~i[541]|i[1609]|~i[678]|~i[1300]|i[996]); -assign o[1589] = ~(~i[927]|~i[541]|i[1300]|i[1675]|~i[188]|i[1620]|i[996]); -assign o[1646] = ~(~i[1675]|~i[927]|~i[541]|~i[1533]|i[1300]|i[1609]|i[996]); -assign o[1665] = ~(~i[1675]|~i[927]|~i[541]|i[1620]|~i[1533]|~i[1300]|i[119]); -assign o[0] = ~(~i[1620]|i[1675]|~i[378]|~i[927]|i[1609]|~i[541]|~i[1300]|i[996]); -assign o[4] = ~(~i[1675]|i[1536]|i[1620]|~i[927]|i[1609]|i[541]|~i[1300]|i[996]); -assign o[76] = ~(i[1536]|~i[927]|i[1675]|i[541]|i[1620]|i[119]|~i[1300]|~i[1609]); -assign o[131] = ~(i[1675]|i[1536]|i[1620]|~i[927]|i[1609]|~i[541]|~i[1300]|i[996]); -assign o[167] = ~(~i[1675]|i[1536]|i[1620]|~i[927]|i[1609]|i[541]|~i[1300]|i[119]); -assign o[179] = ~(~i[1675]|i[1536]|~i[927]|i[541]|i[1620]|i[119]|~i[1300]|~i[1609]); -assign o[245] = ~(~i[1675]|i[1536]|i[541]|i[119]|i[1620]|i[927]|~i[1300]|~i[1609]); -assign o[257] = ~(~i[1675]|i[1536]|i[541]|i[927]|i[1620]|~i[1609]|~i[1300]|i[996]); -assign o[271] = ~(~i[1675]|i[1536]|~i[1620]|~i[927]|i[1609]|~i[541]|~i[1300]|i[996]); -assign o[309] = ~(~i[1575]|~i[927]|i[1675]|~i[541]|i[1620]|i[1300]|~i[1609]|i[996]); -assign o[352] = ~(~i[1675]|~i[927]|~i[1620]|~i[541]|~i[1609]|~i[188]|~i[1300]|i[996]); -assign o[370] = ~(~i[1675]|~i[927]|~i[1620]|~i[541]|~i[378]|~i[1609]|~i[1300]|i[996]); -assign o[487] = ~(~i[1675]|~i[927]|~i[1575]|~i[541]|~i[1620]|~i[1609]|~i[1300]|i[996]); -assign o[528] = ~(~i[1620]|~i[1675]|~i[378]|~i[927]|i[1609]|~i[541]|~i[1300]|i[996]); -assign o[579] = ~(~i[1675]|~i[927]|~i[1620]|~i[541]|i[1609]|~i[678]|~i[1300]|i[996]); -assign o[712] = ~(~i[1575]|~i[1675]|~i[1620]|~i[927]|i[1609]|~i[541]|~i[1300]|i[996]); -assign o[750] = ~(~i[1675]|~i[927]|~i[1575]|~i[541]|i[1620]|~i[1609]|~i[1300]|i[996]); -assign o[784] = ~(i[1675]|~i[927]|~i[1620]|~i[541]|~i[378]|~i[1609]|~i[1300]|i[996]); -assign o[786] = ~(~i[927]|~i[1533]|i[1675]|i[541]|i[1620]|i[119]|~i[1300]|~i[1609]); -assign o[1086] = ~(~i[1575]|~i[927]|i[1675]|~i[541]|i[1620]|~i[1609]|~i[1300]|i[996]); -assign o[1173] = ~(~i[1675]|i[1536]|i[541]|i[927]|i[1620]|~i[1609]|~i[1300]|i[996]); -assign o[1226] = ~(~i[1675]|i[1536]|i[1620]|~i[927]|i[1609]|~i[541]|~i[1300]|i[996]); -assign o[1311] = ~(~i[927]|i[1675]|~i[1620]|~i[541]|~i[1609]|~i[188]|~i[1300]|i[996]); -assign o[1543] = ~(~i[1675]|i[1536]|~i[927]|i[541]|i[1620]|i[119]|~i[1300]|~i[1609]); -assign o[1569] = ~(i[1675]|~i[927]|~i[1620]|~i[541]|~i[1609]|~i[188]|~i[1300]|i[996]); -assign o[1612] = ~(i[1675]|~i[927]|~i[1620]|~i[541]|i[1609]|~i[188]|~i[1300]|i[996]); -assign o[1664] = ~(i[1675]|~i[927]|i[1620]|~i[1533]|i[1609]|i[541]|~i[1300]|i[996]); -assign o[1649] = ~(i[764]|i[197]|i[1109]|i[1382]|i[1057]|~i[1107]|i[1259]|i[712]|i[857]); -assign o[1704] = ~(~i[655]|i[379]|~i[1611]|~i[1359]|~i[377]|~i[622]|~i[1139]|~i[1022]|~i[900]); -assign o[919] = ~(i[1704]&i[1670]); -assign o[1137] = ~(i[790]&i[925]); -assign o[1386] = ~(i[1316]&i[1611]); -assign o[1101] = ~(i[813]&i[46]); -assign o[1077] = ~(i[879]&i[827]); -assign o[757] = ~(i[142]&~i[477]); -assign o[1594] = ~(i[779]&i[604]); -assign o[523] = ~(i[948]&i[1334]); -assign o[473] = ~(i[980]&i[1408]); -assign o[1642] = ~(i[824]&~i[1338]); -assign o[29] = ~(i[787]&i[348]); -assign o[293] = ~(i[200]&i[502]); -assign o[986] = ~(i[276]&i[697]); -assign o[782] = ~(i[1303]&~i[712]); -assign o[673] = ~(i[575]&i[348]); -assign o[504] = ~(~i[24]&~i[197]); -assign o[319] = ~(i[623]&~i[841]); -assign o[701] = ~(~i[1691]&i[681]); -assign o[1525] = ~(~i[143]&i[1628]); -assign o[308] = ~(i[1063]&~i[404]); -assign o[946] = ~(i[844]&i[616]); -assign o[1184] = ~(i[1253]&i[1359]); -assign o[933] = ~(~i[1679]&~i[1176]); -assign o[233] = ~(i[893]&i[68]); -assign o[192] = ~(~i[1721]&i[595]); -assign o[609] = ~(i[743]&i[1551]); -assign o[1459] = ~(i[336]&~i[1084]); -assign o[695] = ~(~i[1425]&i[1450]); -assign o[1542] = ~(i[1345]&i[1022]); -assign o[344] = ~(i[410]&i[622]); -assign o[1111] = ~(i[215]&i[199]); -assign o[651] = ~(~i[1425]&i[308]|i[65]); -assign o[274] = ~(~i[1023]&i[640]|i[860]); -assign o[515] = ~(i[1542]&~i[655]|i[1253]); -assign o[1209] = ~(i[609]&~i[205]|i[1213]); -assign o[1500] = ~(i[379]&~i[1139]|i[1345]); -assign o[263] = ~(i[753]&~i[166]|i[1629]); -assign o[371] = ~(~i[590]&i[1525]|i[555]); -assign o[486] = ~(~i[142]&i[1220]|i[817]); -assign o[1314] = ~(i[427]&i[336]|i[1084]); -assign o[366] = ~(~i[24]&i[1246]|i[1074]); -assign o[1285] = ~(i[1628]&i[590]|i[143]); -assign o[754] = ~(i[443]&i[199]|i[1673]); -assign o[207] = ~(i[293]&~i[584]|i[810]); -assign o[916] = ~(i[412]&i[559]|i[1517]); -assign o[22] = ~(~i[1122]&i[701]|i[193]); -assign o[427] = ~(i[142]&~i[1632]|~i[477]); -assign o[1486] = ~(i[919]&~i[292]|i[200]); -assign o[586] = ~(i[1544]&~i[636]|i[1619]); -assign o[142] = ~(i[1425]&i[1063]|i[404]); -assign o[532] = ~(~i[1314]&i[1241]|i[1217]); -assign o[1475] = ~(i[345]&~i[1188]|i[1097]); -assign o[1308] = ~(i[1314]&i[1398]|i[637]); -assign o[965] = ~(~i[1285]&i[425]|i[295]); -assign o[1039] = ~(i[197]&i[151]|i[456]); -assign o[1327] = ~(i[1314]&~i[1398]|~i[1318]); -assign o[1023] = ~(i[681]&i[1122]|i[1691]); -assign o[732] = ~(i[792]&i[1528]|i[1161]); -assign o[1009] = ~(i[36]&~i[1150]|i[735]); -assign o[1494] = ~(i[1205]&~i[1001]|i[260]); -assign o[450] = ~(i[613]&~i[1287]|i[1159]); -assign o[623] = ~(i[1628]&i[590]|i[143]); -assign o[20] = ~(i[344]&~i[377]|i[1316]); -assign o[1544] = ~(i[1609]&i[620]|i[1115]); -assign o[1290] = ~(i[197]&~i[698]|i[1126]); -assign o[875] = ~(i[523]&~i[49]|i[743]); -assign o[1197] = ~(~i[427]&i[1459]|i[174]); -assign o[632] = ~(~i[902]&i[271]|i[1582]); -assign o[1122] = ~(i[1285]&~i[155]|~i[841]); -assign o[679] = ~(i[739]&~i[1336]|i[479]); -assign o[1037] = ~(i[145]&i[335]|i[1086]); -assign o[474] = ~(i[1184]&~i[900]|i[410]); -assign o[1425] = ~(i[1023]&~i[649]|i[1372]|~i[350]); -assign o[851] = ~(i[1019]&i[125]|i[1294]|i[302]); -assign o[182] = ~(i[660]&~i[1679]|i[0]|~i[17]|~i[1211]); -assign o[11] = ~(~i[1420]&i[1342]|i[4]|i[167]|i[1396]|i[1228]); -assign o[1107] = ~(i[324]&~i[24]|i[1520]|i[1428]|i[1204]|i[492]|i[58]); -assign o[252] = ~(i[691]&i[653]|i[1710]|i[1665]|i[1155]|i[950]|i[301]); -assign o[604] = ~(i[1536]&i[204]|i[197]|i[1582]|i[804]|i[1311]|i[1031]|i[1428]); -assign o[472] = ~(~i[197]&i[706]|i[197]&i[1373]); -assign o[428] = ~(~i[197]&i[40]|i[197]&i[706]); -assign o[613] = ~(~i[697]&i[393]|~i[1341]&i[697]); -assign o[262] = ~(~i[1008]&i[685]|~i[1321]&i[1008]); -assign o[468] = ~(~i[197]&i[1373]|i[197]&i[940]); -assign o[1091] = ~(~i[197]&i[537]|i[197]&i[40]); -assign o[626] = ~(~i[493]&i[1269]|~i[1269]&i[1530]); -assign o[345] = ~(i[986]&~i[1341]|i[393]&i[876]); -assign o[1181] = ~(i[754]&~i[493]|~i[754]&i[1442]); -assign o[739] = ~(~i[893]&i[811]|i[893]&i[1257]); -assign o[1205] = ~(i[811]&i[1018]|i[233]&i[1257]); -assign o[1106] = ~(i[258]&~i[1562]|i[335]&i[1540]|i[76]|i[1543]|i[1658]|i[245]|i[84]); -assign o[1717] = ~(i[258]&i[1562]|i[335]&i[1601]|i[1173]|i[1233]|i[60]|i[382]|i[1512]); -assign o[1495] = ~(~i[1302]&i[781]|i[1457]&i[99]|i[1609]&~i[974]); -assign o[566] = ~(i[1170]&i[1607]|~i[991]&i[781]|~i[443]&i[1268]); -assign o[845] = ~(~i[1473]&i[781]|~i[1124]&i[1609]|i[553]&i[1078]); -assign o[299] = ~(i[408]&i[1436]|i[1614]&i[44]|~i[833]&i[1111]|~i[1283]); -assign o[1082] = ~(~i[1049]&~i[1108]|i[412]&~i[338]|i[1051]&i[279]|i[1609]&~i[1104]); -wire sb_local_1287 = i[801]|i[1263]|~i[621]|~i[512]|i[1698]; -wire idb_local_1473 = i[1331]|~i[398]|~i[878]|i[710]&~i[1221]|~i[1577]; -wire adh_local_1651 = ~i[1683]|~i[598]|i[710]&~i[1020]; -wire db2sb_1287 = idb_local_1473 & ~i[1527]; -wire sb2db_1473 = sb_local_1287 & ~i[1527]; -wire adh2sb_1287 = adh_local_1651 & ~i[1602]; -wire sb2adh_1651 = sb_local_1287 & ~i[1602]; -MUX #(8) mux_sb_1287 (.o(o[1287]), .i(i[1287]), .s({i[943],i[801],i[1263],~i[621],~i[512],i[1698],db2sb_1287,adh2sb_1287}), .d({i[657],i[573],i[1],~i[752],~i[276],i[978],i[1473],i[1651]})); -MUX #(7) mux_idb_1473 (.o(o[1473]), .i(i[1473]), .s({i[943],i[1331],~i[398],~i[878],i[710]&~i[1221],sb2db_1473,~i[1577]}), .d({i[657],i[978],~i[114],i[1411],~i[1485],i[1287],~i[334]})); -MUX #(6) mux_adl_1242 (.o(o[1242]), .i(i[1242]), .s({i[943],~i[339],~i[745],~i[897],i[710]&~i[1121],i[45]}), .d({i[657],~i[752],~i[276],i[1411],~i[1485],i[558]})); -MUX #(5) mux_adh_1651 (.o(o[1651]), .i(i[1651]), .s({i[943],~i[1683],~i[598],i[710]&~i[1020], sb2adh_1651}), .d({i[657],i[558],~i[114],~i[1485],i[1287]})); -MUX #(2) mux_pcl_655 (.o(o[655]), .i(i[655]), .s({i[898],i[414]}), .d({i[1411],i[1242]})); -MUX #(2) mux_pch_502 (.o(o[502]), .i(i[502]), .s({i[48],i[741]}), .d({i[1651],~i[114]})); -wire sb_local_54 = i[801]|i[1263]|~i[621]|~i[512]|i[1698]; -wire idb_local_1108 = i[1331]|~i[398]|~i[878]|i[710]&~i[1221]|~i[1577]; -wire adh_local_407 = ~i[683]|~i[598]|i[710]&~i[1020]; -wire db2sb_54 = idb_local_1108 & ~i[1527]; -wire sb2db_1108 = sb_local_54 & ~i[1527]; -wire adh2sb_54 = adh_local_407 & ~i[1602]; -wire sb2adh_407 = sb_local_54 & ~i[1602]; -MUX #(8) mux_sb_54 (.o(o[54]), .i(i[54]), .s({i[943],i[801],i[1263],~i[621],~i[512],i[1698],db2sb_54,adh2sb_54}), .d({i[657],i[64],i[1216],~i[418],~i[394],i[737],i[1108],i[407]})); -MUX #(7) mux_idb_1108 (.o(o[1108]), .i(i[1108]), .s({i[943],i[1331],~i[398],~i[878],i[710]&~i[1221],sb2db_1108,~i[1577]}), .d({i[657],i[737],~i[780],i[526],~i[116],i[54],i[32]})); -MUX #(6) mux_adl_413 (.o(o[413]), .i(i[413]), .s({i[943],~i[339],~i[745],~i[897],i[710]&~i[1121],~i[357]}), .d({i[657],~i[418],~i[394],i[526],~i[116],i[558]})); -MUX #(5) mux_adh_407 (.o(o[407]), .i(i[407]), .s({i[943],~i[683],~i[598],i[710]&~i[1020], sb2adh_407}), .d({i[657],i[558],~i[780],~i[116],i[54]})); -MUX #(2) mux_pcl_1139 (.o(o[1139]), .i(i[1139]), .s({i[898],i[414]}), .d({i[526],i[413]})); -MUX #(2) mux_pch_1670 (.o(o[1670]), .i(i[1670]), .s({i[48],i[741]}), .d({i[407],~i[780]})); -wire sb_local_1150 = i[801]|i[1263]|~i[621]|~i[512]|i[1698]; -wire idb_local_991 = i[1331]|~i[398]|~i[878]|i[710]&~i[1221]|~i[1577]; -wire adh_local_52 = ~i[1683]|~i[598]|i[710]&~i[1020]; -wire db2sb_1150 = idb_local_991 & ~i[1527]; -wire sb2db_991 = sb_local_1150 & ~i[1527]; -wire adh2sb_1150 = adh_local_52 & ~i[1602]; -wire sb2adh_52 = sb_local_1150 & ~i[1602]; -MUX #(8) mux_sb_1150 (.o(o[1150]), .i(i[1150]), .s({i[943],i[801],i[1263],~i[621],~i[512],i[1698],db2sb_1150,adh2sb_1150}), .d({i[657],i[1148],i[98],~i[1064],~i[697],i[1234],i[991],i[52]})); -MUX #(7) mux_idb_991 (.o(o[991]), .i(i[991]), .s({i[943],i[1331],~i[398],~i[878],i[710]&~i[1221],sb2db_991,~i[1577]}), .d({i[657],i[1234],i[126],~i[1102],~i[576],i[1150],i[627]})); -MUX #(6) mux_adl_1282 (.o(o[1282]), .i(i[1282]), .s({i[943],~i[339],~i[745],~i[897],i[710]&~i[1121],~i[170]}), .d({i[657],~i[1064],~i[697],~i[1102],~i[576],i[558]})); -MUX #(5) mux_adh_52 (.o(o[52]), .i(i[52]), .s({i[943],~i[1683],~i[598],i[710]&~i[1020], sb2adh_52}), .d({i[657],i[558],i[126],~i[576],i[1150]})); -MUX #(2) mux_pcl_1022 (.o(o[1022]), .i(i[1022]), .s({i[898],i[414]}), .d({~i[1102],i[1282]})); -MUX #(2) mux_pch_292 (.o(o[292]), .i(i[292]), .s({i[48],i[741]}), .d({i[52],i[126]})); -wire sb_local_1188 = i[801]|i[1263]|~i[621]|~i[512]|i[1698]; -wire idb_local_1302 = i[1331]|~i[398]|~i[878]|i[710]&~i[1221]|~i[1577]; -wire adh_local_315 = ~i[1683]|~i[598]|i[710]&~i[1020]; -wire db2sb_1188 = idb_local_1302 & ~i[1527]; -wire sb2db_1302 = sb_local_1188 & ~i[1527]; -wire adh2sb_1188 = adh_local_315 & ~i[1602]; -wire sb2adh_315 = sb_local_1188 & ~i[1602]; -MUX #(8) mux_sb_1188 (.o(o[1188]), .i(i[1188]), .s({i[943],i[801],i[1263],~i[621],~i[512],i[1698],db2sb_1188,adh2sb_1188}), .d({i[657],i[305],i[1648],~i[828],~i[495],i[162],i[1302],i[315]})); -MUX #(7) mux_idb_1302 (.o(o[1302]), .i(i[1302]), .s({i[943],i[1331],~i[398],~i[878],i[710]&~i[1221],sb2db_1302,~i[1577]}), .d({i[657],i[162],i[1061],~i[868],~i[1284],i[1188],i[348]})); -MUX #(6) mux_adl_684 (.o(o[684]), .i(i[684]), .s({i[943],~i[339],~i[745],~i[897],i[710]&~i[1121],i[558]}), .d({i[657],~i[828],~i[495],~i[868],~i[1284],i[558]})); -MUX #(5) mux_adh_315 (.o(o[315]), .i(i[315]), .s({i[943],~i[1683],~i[598],i[710]&~i[1020], sb2adh_315}), .d({i[657],i[558],i[1061],~i[1284],i[1188]})); -MUX #(2) mux_pcl_1359 (.o(o[1359]), .i(i[1359]), .s({i[898],i[414]}), .d({~i[868],i[684]})); -MUX #(2) mux_pch_584 (.o(o[584]), .i(i[584]), .s({i[48],i[741]}), .d({i[315],i[1061]})); -wire sb_local_1405 = i[801]|i[1263]|~i[621]|~i[512]|i[1698]; -wire idb_local_892 = i[1331]|~i[398]|~i[878]|i[710]&~i[1221]|~i[1577]; -wire adh_local_1160 = ~i[1683]|~i[598]|i[710]&~i[1020]; -wire db2sb_1405 = idb_local_892 & ~i[1527]; -wire sb2db_892 = sb_local_1405 & ~i[1527]; -wire adh2sb_1405 = adh_local_1160 & ~i[1602]; -wire sb2adh_1160 = sb_local_1405 & ~i[1602]; -MUX #(8) mux_sb_1405 (.o(o[1405]), .i(i[1405]), .s({i[943],i[801],i[1263],~i[621],~i[512],i[1698],db2sb_1405,adh2sb_1405}), .d({i[657],i[989],i[85],~i[1603],~i[1490],i[727],i[892],i[1160]})); -MUX #(7) mux_idb_892 (.o(o[892]), .i(i[892]), .s({i[943],i[1331],~i[398],~i[878],i[710]&~i[1221],sb2db_892,~i[1577]}), .d({i[657],i[727],~i[820],i[15],~i[1516],i[1405],i[827]})); -MUX #(6) mux_adl_1437 (.o(o[1437]), .i(i[1437]), .s({i[943],~i[339],~i[745],~i[897],i[710]&~i[1121],i[558]}), .d({i[657],~i[1603],~i[1490],i[15],~i[1516],i[558]})); -MUX #(5) mux_adh_1160 (.o(o[1160]), .i(i[1160]), .s({i[943],~i[1683],~i[598],i[710]&~i[1020], sb2adh_1160}), .d({i[657],i[558],~i[820],~i[1516],i[1405]})); -MUX #(2) mux_pcl_900 (.o(o[900]), .i(i[900]), .s({i[898],i[414]}), .d({i[15],i[1437]})); -MUX #(2) mux_pch_948 (.o(o[948]), .i(i[948]), .s({i[48],i[741]}), .d({i[1160],~i[820]})); -wire sb_local_166 = i[801]|i[1263]|~i[621]|~i[512]|i[1698]; -wire idb_local_1503 = i[1331]|~i[398]|~i[878]|i[710]&~i[1221]|i[558]; -wire adh_local_483 = ~i[1683]|~i[598]|i[710]&~i[1020]; -wire db2sb_166 = idb_local_1503 & ~i[1527]; -wire sb2db_1503 = sb_local_166 & ~i[1527]; -wire adh2sb_166 = adh_local_483 & ~i[1602]; -wire sb2adh_483 = sb_local_166 & ~i[1602]; -MUX #(8) mux_sb_166 (.o(o[166]), .i(i[166]), .s({i[943],i[801],i[1263],~i[621],~i[512],i[1698],db2sb_166,adh2sb_166}), .d({i[657],i[615],i[589],~i[601],~i[893],i[858],i[1503],i[483]})); -MUX #(7) mux_idb_1503 (.o(o[1503]), .i(i[1503]), .s({i[943],i[1331],~i[398],~i[878],i[710]&~i[1221],sb2db_1503,i[558]}), .d({i[657],i[858],i[469],~i[1326],~i[498],i[166],i[558]})); -MUX #(6) mux_adl_1630 (.o(o[1630]), .i(i[1630]), .s({i[943],~i[339],~i[745],~i[897],i[710]&~i[1121],i[558]}), .d({i[657],~i[601],~i[893],~i[1326],~i[498],i[558]})); -MUX #(5) mux_adh_483 (.o(o[483]), .i(i[483]), .s({i[943],~i[1683],~i[598],i[710]&~i[1020], sb2adh_483}), .d({i[657],i[558],i[469],~i[498],i[166]})); -MUX #(2) mux_pcl_622 (.o(o[622]), .i(i[622]), .s({i[898],i[414]}), .d({~i[1326],i[1630]})); -MUX #(2) mux_pch_49 (.o(o[49]), .i(i[49]), .s({i[48],i[741]}), .d({i[483],i[469]})); -wire sb_local_1336 = i[801]|i[1263]|~i[621]|~i[512]|i[1698]; -wire idb_local_833 = i[1331]|~i[398]|~i[878]|i[710]&~i[1221]|~i[1577]; -wire adh_local_13 = ~i[1683]|~i[598]|i[710]&~i[1020]; -wire db2sb_1336 = idb_local_833 & ~i[1527]; -wire sb2db_833 = sb_local_1336 & ~i[1527]; -wire adh2sb_1336 = adh_local_13 & ~i[1602]; -wire sb2adh_13 = sb_local_1336 & ~i[1602]; -MUX #(8) mux_sb_1336 (.o(o[1336]), .i(i[1336]), .s({i[943],i[801],i[1263],~i[621],~i[512],i[1698],db2sb_1336,adh2sb_1336}), .d({i[657],i[115],i[448],~i[1029],~i[68],i[1136],i[833],i[13]})); -MUX #(7) mux_idb_833 (.o(o[833]), .i(i[833]), .s({i[943],i[1331],~i[398],~i[878],i[710]&~i[1221],sb2db_833,~i[1577]}), .d({i[657],i[1136],~i[751],i[993],~i[1537],i[1336],i[1625]})); -MUX #(6) mux_adl_121 (.o(o[121]), .i(i[121]), .s({i[943],~i[339],~i[745],~i[897],i[710]&~i[1121],i[558]}), .d({i[657],~i[1029],~i[68],i[993],~i[1537],i[558]})); -MUX #(5) mux_adh_13 (.o(o[13]), .i(i[13]), .s({i[943],~i[1683],~i[598],i[710]&~i[1020], sb2adh_13}), .d({i[657],i[558],~i[751],~i[1537],i[1336]})); -MUX #(2) mux_pcl_377 (.o(o[377]), .i(i[377]), .s({i[898],i[414]}), .d({i[993],i[121]})); -MUX #(2) mux_pch_1551 (.o(o[1551]), .i(i[1551]), .s({i[48],i[741]}), .d({i[13],~i[751]})); -wire sb_local_1001 = i[801]|i[1263]|~i[621]|i[1333]|i[1698]; -wire idb_local_493 = i[1331]|~i[398]|~i[878]|i[710]&~i[1221]|~i[1577]; -wire adh_local_1539 = ~i[1683]|~i[598]|i[710]&~i[1020]; -wire db2sb_1001 = idb_local_493 & ~i[1527]; -wire sb2db_493 = sb_local_1001 & ~i[1527]; -wire adh2sb_1001 = adh_local_1539 & ~i[1602]; -wire sb2adh_1539 = sb_local_1001 & ~i[1602]; -MUX #(8) mux_sb_1001 (.o(o[1001]), .i(i[1001]), .s({i[943],i[801],i[1263],~i[621],i[1333],i[1698],db2sb_1001,adh2sb_1001}), .d({i[657],i[843],i[777],~i[181],~i[1123],i[1653],i[493],i[1539]})); -MUX #(7) mux_idb_493 (.o(o[493]), .i(i[493]), .s({i[943],i[1331],~i[398],~i[878],i[710]&~i[1221],sb2db_493,~i[1577]}), .d({i[657],i[1653],i[663],~i[536],~i[529],i[1001],i[69]})); -MUX #(6) mux_adl_1299 (.o(o[1299]), .i(i[1299]), .s({i[943],~i[339],~i[745],~i[897],i[710]&~i[1121],i[558]}), .d({i[657],~i[181],~i[1123],~i[536],~i[529],i[558]})); -MUX #(5) mux_adh_1539 (.o(o[1539]), .i(i[1539]), .s({i[943],~i[1683],~i[598],i[710]&~i[1020], sb2adh_1539}), .d({i[657],i[558],i[663],~i[529],i[1001]})); -MUX #(2) mux_pcl_1611 (.o(o[1611]), .i(i[1611]), .s({i[898],i[414]}), .d({~i[536],i[1299]})); -MUX #(2) mux_pch_205 (.o(o[205]), .i(i[205]), .s({i[48],i[741]}), .d({i[1539],i[663]})); -assign o[430] = (i[756]^i[412]) & i[899]; -assign o[1536] = ~(i[964]|i[732]); -assign o[17] = ~(i[964]|i[732]); -assign o[779] = ~((i[787]|i[1081]|~i[1219])&~i[197]); -assign o[1035] = ~(i[943]|i[943]); -assign o[1085] = ~(~i[197]&(~i[17]|~i[636]&i[1544])|~i[666]&i[197]); -assign o[379] = ~((i[1581]|i[1570])&i[1472]); -assign o[480] = ~((~i[334]|~i[675])&i[264]); -assign o[1229] = ~((i[1670]|i[1704])&i[919]); -assign o[484] = ~((i[1611]|i[1316])&i[1386]); -assign o[1408] = ~((i[575]|i[1466])&i[1044]); -assign o[1657] = ~((i[1334]|i[948])&i[523]); -assign o[1402] = ~((i[502]|i[200])&i[293]); -assign o[1631] = ~((i[1359]|i[1253])&i[1184]); -assign o[1192] = ~((i[1551]|i[743])&i[609]); -assign o[1073] = ~((i[410]|i[622])&i[344]); -assign o[1099] = ~((i[1345]|i[1022])&i[1542]); -assign o[629] = ~((~i[636]|~i[17])&i[480]|i[50]); -assign o[696] = ~((i[1343]|i[877])&~i[660]|~i[357]); -assign o[1372] = ~((i[1691]|i[319])&(i[1610]|i[388])|~i[1450]); -assign o[333] = ~((i[757]|i[1459])&(i[570]|i[269])|~i[1450]); -assign o[1303] = ~((i[1601]|i[1540])&i[335]); -assign o[1393] = ~i[873]; -assign o[945] = ~i[1288]; -assign o[1591] = ~i[1418]; -assign o[650] = ~i[823]; -assign o[175] = ~i[1266]; -assign o[82] = ~i[527]; -assign o[1005] = ~i[222]; -assign o[1349] = ~i[158]; -assign o[1331] = ~i[266]&i[710]&~i[943]; -assign o[1698] = ~i[55]&i[710]&~i[943]; -assign o[1263] = ~i[1404]&i[710]&~i[943]; -assign o[801] = ~i[1113]&i[710]&~i[943]; -assign o[414] = ~i[265]&i[710]&~i[943]; -assign o[654] = ~i[796]&i[710]&~i[943]; -assign o[859] = ~i[688]&i[710]&~i[943]; -assign o[325] = ~i[460]&i[710]&~i[943]; -assign o[984] = ~i[1027]&i[710]&~i[943]; -assign o[549] = ~i[360]&i[710]&~i[943]; -assign o[1068] = ~i[805]&i[710]&~i[943]; -assign o[437] = ~i[1477]&i[710]&~i[943]; -assign o[1186] = ~i[459]&i[710]&~i[943]; -assign o[48] = ~i[1162]&i[710]&~i[943]; -assign o[741] = ~i[1509]&i[710]&~i[943]; -assign o[534] = ~i[1505]&i[710]&~i[943]; -assign o[898] = ~i[509]&i[710]&~i[943]; -assign o[874] = ~i[521]&i[710]&~i[943]; -assign o[710] = ~i[1171]; -assign o[943] = i[1171]; -assign o[297] = ~(i[1032]|~i[1297]&i[943]); -assign o[1032] = ~(i[297]|i[1297]&i[943]); -assign o[854] = ~(i[975]|~i[159]&i[943]); -assign o[330] = ~(i[807]|i[103]&i[943]); -assign o[807] = ~(i[330]|~i[103]&i[943]); -assign o[975] = ~(i[854]|i[159]&i[943]); -assign o[539] = ~i[666]; -assign o[1156] = ~i[402]; -assign o[736] = i[710]&~i[190]? i[1630] : i[736]; -assign o[148] = i[710]&~i[610]? i[52] : i[148]; -assign o[451] = i[710]&~i[190]? i[1282] : i[451]; -assign o[1340] = i[710]&~i[190]? i[1242] : i[1340]; -assign o[211] = i[710]&~i[190]? i[684] : i[211]; -assign o[1493] = i[710]&~i[190]? i[1299] : i[1493]; -assign o[1443] = i[710]&~i[610]? i[1651] : i[1443]; -assign o[195] = i[710]&~i[610]? i[1539] : i[195]; -assign o[887] = i[710]&~i[190]? i[121] : i[887]; -assign o[230] = i[710]&~i[610]? i[407] : i[230]; -assign o[399] = i[710]&~i[610]? i[315] : i[399]; -assign o[349] = i[710]&~i[610]? i[483] : i[349]; -assign o[672] = i[710]&~i[610]? i[13] : i[672]; -assign o[268] = i[710]&~i[190]? i[413] : i[268]; -assign o[435] = i[710]&~i[190]? i[1437] : i[435]; -assign o[1237] = i[710]&~i[610]? i[1160] : i[1237]; -assign o[1532] = i[874]? i[1188] : i[654]? ~i[828] : i[1532]; -assign o[828] = i[943]? ~i[1532] : i[828]; -assign o[1098] = i[874]? i[166] : i[654]? ~i[601] : i[1098]; -assign o[601] = i[943]? ~i[1098] : i[601]; -assign o[1435] = i[874]? i[1001] : i[654]? ~i[181] : i[1435]; -assign o[181] = i[943]? ~i[1435] : i[181]; -assign o[1702] = i[874]? i[1405] : i[654]? ~i[1603] : i[1702]; -assign o[1603] = i[943]? ~i[1702] : i[1603]; -assign o[1403] = i[874]? i[54] : i[654]? ~i[418] : i[1403]; -assign o[418] = i[943]? ~i[1403] : i[418]; -assign o[1212] = i[874]? i[1336] : i[654]? ~i[1029] : i[1212]; -assign o[1029] = i[943]? ~i[1212] : i[1029]; -assign o[81] = i[874]? i[1287] : i[654]? ~i[752] : i[81]; -assign o[752] = i[943]? ~i[81] : i[752]; -assign o[183] = i[874]? i[1150] : i[654]? ~i[1064] : i[183]; -assign o[1064] = i[943]? ~i[183] : i[1064]; -assign o[737] = i[534]? i[54] : i[737]; -assign o[1653] = i[534]? i[1494] : i[1653]; -assign o[305] = i[325]? i[1188] : i[305]; -assign o[978] = i[534]? i[450] : i[978]; -assign o[85] = i[1186]? i[1405] : i[85]; -assign o[727] = i[534]? i[1405] : i[727]; -assign o[989] = i[325]? i[1405] : i[989]; -assign o[448] = i[1186]? i[1336] : i[448]; -assign o[1] = i[1186]? i[1287] : i[1]; -assign o[162] = i[534]? i[1475] : i[162]; -assign o[615] = i[325]? i[166] : i[615]; -assign o[1216] = i[1186]? i[54] : i[1216]; -assign o[589] = i[1186]? i[166] : i[589]; -assign o[64] = i[325]? i[54] : i[64]; -assign o[1148] = i[325]? i[1150] : i[1148]; -assign o[1136] = i[534]? i[679] : i[1136]; -assign o[98] = i[1186]? i[1150] : i[98]; -assign o[115] = i[325]? i[1336] : i[115]; -assign o[573] = i[325]? i[1287] : i[573]; -assign o[1648] = i[1186]? i[1188] : i[1648]; -assign o[1234] = i[534]? i[1009] : i[1234]; -assign o[777] = i[1186]? i[1001] : i[777]; -assign o[843] = i[325]? i[1001] : i[843]; -assign o[858] = i[534]? i[263] : i[858]; -assign o[1609] = i[710]&i[879]? i[928] : i[1609]; -assign o[1675] = i[710]&i[879]? i[1309] : i[1675]; -assign o[1620] = i[710]&i[879]? ~i[1587] : i[1620]; -assign o[541] = i[710]&i[879]? ~i[1410] : i[541]; -assign o[1300] = i[710]&i[879]? ~i[1671] : i[1300]; -assign o[119] = i[710]&i[879]? ~i[809] : i[119]; -assign o[310] = i[710]&i[879]? ~i[1622] : i[310]; -assign o[927] = i[710]&i[879]? ~i[540] : i[927]; -MUX #(5) mux_alu_out_68 (.o(o[68]), .i(i[68]), .s({~i[226]&i[943],~i[1674]&i[943],~i[95]&i[943],~i[101]&i[943],~i[1529]&i[943]}), .d({i[1318],i[1197],i[1084],i[1459],i[336]})); -MUX #(5) mux_alu_out_276 (.o(o[276]), .i(i[276]), .s({~i[1674]&i[943],~i[95]&i[943],~i[101]&i[943],~i[1529]&i[943],~i[226]&i[943]}), .d({i[22],i[1691],i[701],i[681],i[350]})); -MUX #(5) mux_alu_out_495 (.o(o[495]), .i(i[495]), .s({~i[1674]&i[943],~i[95]&i[943],~i[101]&i[943],~i[226]&i[943],~i[1529]&i[943]}), .d({i[274],i[649],~i[640],i[1063],i[350]})); -MUX #(5) mux_alu_out_893 (.o(o[893]), .i(i[893]), .s({~i[1674]&i[943],~i[226]&i[943],~i[95]&i[943],~i[101]&i[943],~i[1529]&i[943]}), .d({i[486],i[336],i[1632],~i[1220],i[477]})); -MUX #(5) mux_alu_out_394 (.o(o[394]), .i(i[394]), .s({~i[1674]&i[943],~i[1529]&i[943],~i[95]&i[943],~i[101]&i[943],~i[226]&i[943]}), .d({i[371],i[1628],i[143],i[1525],i[841]})); -MUX #(5) mux_alu_out_697 (.o(o[697]), .i(i[697]), .s({~i[95]&i[943],~i[101]&i[943],~i[1674]&i[943],~i[226]&i[943],~i[1529]&i[943]}), .d({i[155],~i[425],i[965],i[681],i[841]})); -MUX #(5) mux_alu_out_1490 (.o(o[1490]), .i(i[1490]), .s({~i[226]&i[943],~i[1674]&i[943],~i[101]&i[943],~i[1529]&i[943],~i[95]&i[943]}), .d({i[477],i[651],i[308],i[1063],i[404]})); -MUX #(5) mux_alu_out_1123 (.o(o[1123]), .i(i[1123]), .s({~i[1529]&i[943],~i[101]&i[943],~i[95]&i[943],~i[1674]&i[943],~i[226]&i[943]}), .d({i[1318],~i[1241],i[1398],i[532],i[657]})); -MUX #(2) mux_alua_1627 (.o(o[1627]), .i(i[1627]), .s({i[549],i[984]}), .d({i[1336],i[558]})); -MUX #(3) mux_alub_235 (.o(o[235]), .i(i[235]), .s({ i[1068],i[859],i[437]}), .d({~i[833],i[833],i[121]})); -assign o[1084] = ~(i[235]|i[1627]); -assign o[336] = ~(i[235]&i[1627]); -MUX #(2) mux_alua_1522 (.o(o[1522]), .i(i[1522]), .s({i[549],i[984]}), .d({i[1001],i[558]})); -MUX #(3) mux_alub_1535 (.o(o[1535]), .i(i[1535]), .s({ i[1068],i[859],i[437]}), .d({~i[493],i[493],i[1299]})); -assign o[1398] = ~(i[1535]|i[1522]); -assign o[1318] = ~(i[1535]&i[1522]); -MUX #(2) mux_alua_1332 (.o(o[1332]), .i(i[1332]), .s({i[549],i[984]}), .d({i[1287],i[558]})); -MUX #(3) mux_alub_704 (.o(o[704]), .i(i[704]), .s({ i[1068],i[859],i[437]}), .d({~i[1473],i[1473],i[1242]})); -assign o[1691] = ~(i[704]|i[1332]); -assign o[681] = ~(i[704]&i[1332]); -MUX #(2) mux_alua_1142 (.o(o[1142]), .i(i[1142]), .s({i[549],i[984]}), .d({i[1405],i[558]})); -MUX #(3) mux_alub_1645 (.o(o[1645]), .i(i[1645]), .s({ i[1068],i[859],i[437]}), .d({~i[892],i[892],i[1437]})); -assign o[404] = ~(i[1645]|i[1142]); -assign o[1063] = ~(i[1645]&i[1142]); -MUX #(2) mux_alua_1248 (.o(o[1248]), .i(i[1248]), .s({i[549],i[984]}), .d({i[1150],i[558]})); -MUX #(3) mux_alub_1432 (.o(o[1432]), .i(i[1432]), .s({ i[1068],i[859],i[437]}), .d({~i[991],i[991],i[1282]})); -assign o[155] = ~(i[1432]|i[1248]); -assign o[841] = ~(i[1432]&i[1248]); -MUX #(2) mux_alua_1167 (.o(o[1167]), .i(i[1167]), .s({i[549],i[984]}), .d({i[54],i[558]})); -MUX #(3) mux_alub_977 (.o(o[977]), .i(i[977]), .s({ i[1068],i[859],i[437]}), .d({~i[1108],i[1108],i[413]})); -assign o[143] = ~(i[977]|i[1167]); -assign o[1628] = ~(i[977]&i[1167]); -MUX #(2) mux_alua_530 (.o(o[530]), .i(i[530]), .s({i[549],i[984]}), .d({i[166],i[558]})); -MUX #(3) mux_alub_1678 (.o(o[1678]), .i(i[1678]), .s({ i[1068],i[859],i[437]}), .d({~i[1503],i[1503],i[1630]})); -assign o[1632] = ~(i[1678]|i[530]); -assign o[477] = ~(i[1678]&i[530]); -MUX #(2) mux_alua_1680 (.o(o[1680]), .i(i[1680]), .s({i[549],i[984]}), .d({i[1188],i[558]})); -MUX #(3) mux_alub_96 (.o(o[96]), .i(i[96]), .s({ i[1068],i[859],i[437]}), .d({~i[1302],i[1302],i[684]})); -assign o[649] = ~(i[96]|i[1680]); -assign o[350] = ~(i[96]&i[1680]); -assign o[758] = i[943] ? ~i[1005] : i[758]; -assign o[361] = i[943] ? ~i[82] : i[361]; -assign o[688] = i[943] ? i[1594] : i[688]; -assign o[1565] = i[943] ? i[1450] : i[1565]; -assign o[1027] = i[943] ? i[1649] : i[1027]; -assign o[760] = i[943] ? i[629] : i[760]; -assign o[610] = i[943] ? i[696] : i[610]; -assign o[1436] = i[943] ? i[1155] : i[1436]; -assign o[1078] = i[943] ? i[334] : i[1078]; -assign o[1341] = i[943] ? i[695] : i[1341]; -assign o[56] = i[943] ? i[824] : i[56]; -assign o[1485] = i[943] ? ~i[945] : i[1485]; -assign o[1338] = i[710] ? i[720] : i[1338]; -assign o[449] = i[943] ? ~i[1395] : i[449]; -assign o[45] = i[943] ? i[1712] : i[45]; -assign o[1252] = i[943] ? i[1374] : i[1252]; -assign o[899] = i[943] ? i[19] : i[899]; -assign o[1126] = i[943] ? i[1465] : i[1126]; -assign o[680] = i[943] ? i[1688] : i[680]; -assign o[415] = i[943] ? i[1196] : i[415]; -assign o[968] = i[943] ? ~i[366] : i[968]; -assign o[974] = i[943] ? i[774] : i[974]; -assign o[1404] = i[943] ? i[1106] : i[1404]; -assign o[1577] = i[943] ? i[1391] : i[1577]; -assign o[339] = i[943] ? i[632] : i[339]; -assign o[685] = i[943] ? ~i[1447] : i[685]; -assign o[596] = i[943] ? i[1085] : i[596]; -assign o[1291] = i[710] ? i[1382] : i[1291]; -assign o[527] = i[710] ? ~i[991] : i[527]; -assign o[666] = i[710] ? i[1380] : i[666]; -assign o[47] = i[710] ? ~i[865] : i[47]; -assign o[1221] = i[943] ? i[104] : i[1221]; -assign o[215] = i[943] ? i[1379] : i[215]; -assign o[759] = i[710] ? i[187] : i[759]; -assign o[1693] = i[943] ? i[264] : i[1693]; -assign o[799] = i[943] ? i[264] : i[799]; -assign o[40] = i[943] ? i[1575] : i[40]; -assign o[1602] = i[943] ? i[506] : i[1602]; -assign o[94] = i[710] ? ~i[1672] : i[94]; -assign o[456] = i[943] ? i[191] : i[456]; -assign o[1121] = i[943] ? i[1225] : i[1121]; -assign o[1530] = i[943] ? ~i[756] : i[1530]; -assign o[780] = i[943] ? i[1229] : i[780]; -assign o[554] = i[943] ? i[17] : i[554]; -assign o[581] = i[943] ? i[599] : i[581]; -assign o[627] = i[710] ? i[566] : i[627]; -assign o[1579] = i[710] ? i[187] : i[1579]; -assign o[338] = i[943] ? i[252] : i[338]; -assign o[199] = i[943] ? i[327] : i[199]; -assign o[1269] = i[943] ? ~i[636] : i[1269]; -assign o[158] = i[710] ? ~i[493] : i[158]; -assign o[537] = i[943] ? ~i[666] : i[537]; -assign o[576] = i[943] ? ~i[82] : i[576]; -assign o[18] = i[710] ? i[468] : i[18]; -assign o[1699] = i[943] ? ~i[94] : i[1699]; -assign o[706] = i[943] ? i[678] : i[706]; -assign o[536] = i[943] ? i[484] : i[536]; -assign o[940] = i[943] ? i[378] : i[940]; -assign o[126] = i[943] ? i[1486] : i[126]; -assign o[1411] = i[943] ? i[515] : i[1411]; -assign o[751] = i[943] ? i[1192] : i[751]; -assign o[590] = i[710] ? i[1178] : i[590]; -assign o[868] = i[943] ? i[1631] : i[868]; -assign o[360] = i[943] ? ~i[1649] : i[360]; -assign o[1505] = i[943] ? i[1455] : i[1505]; -assign o[460] = i[943] ? i[616] : i[460]; -assign o[151] = i[943] ? ~i[24] : i[151]; -assign o[526] = i[943] ? i[1500] : i[526]; -assign o[1533] = i[710] ? i[1180] : i[1533]; -assign o[529] = i[943] ? ~i[1349] : i[529]; -assign o[1509] = i[943] ? ~i[272] : i[1509]; -assign o[1266] = i[710] ? ~i[1503] : i[1266]; -assign o[1176] = i[943] ? ~i[1409] : i[1176]; -assign o[671] = i[710] ? ~i[197] : i[671]; -assign o[99] = i[943] ? ~i[348] : i[99]; -assign o[1652] = i[943] ? i[385] : i[1652]; -assign o[357] = i[943] ? ~i[1465] : i[357]; -assign o[1442] = i[943] ? ~i[69] : i[1442]; -assign o[1177] = i[943] ? i[1069] : i[1177]; -assign o[993] = i[943] ? i[20] : i[993]; -assign o[190] = i[943] ? i[1101] : i[190]; -assign o[24] = i[710] ? i[1039] : i[24]; -assign o[1333] = i[943] ? i[80] : i[1333]; -assign o[1409] = i[710] ? i[916] : i[1409]; -assign o[1020] = i[943] ? i[1705] : i[1020]; -assign o[1274] = i[710] ? ~i[1699] : i[1274]; -assign o[55] = i[943] ? i[11] : i[55]; -assign o[644] = i[710] ? i[428] : i[644]; -assign o[521] = i[943] ? i[1358] : i[521]; -assign o[1326] = i[943] ? i[1073] : i[1326]; -assign o[69] = i[710] ? i[1181] : i[69]; -assign o[663] = i[943] ? i[1209] : i[663]; -assign o[398] = i[943] ? i[824] : i[398]; -assign o[1124] = i[943] ? i[1065] : i[1124]; -assign o[1272] = i[710] ? i[197] : i[1272]; -assign o[1574] = i[943] ? i[1228] : i[1574]; -assign o[1438] = i[943] ? i[504] : i[1438]; -assign o[1360] = i[710] ? i[1091] : i[1360]; -assign o[1713] = i[943] ? i[501] : i[1713]; -assign o[1276] = i[710] ? i[197] : i[1276]; -assign o[1049] = i[943] ? i[160] : i[1049]; -assign o[73] = i[943] ? ~i[366] : i[73]; -assign o[1102] = i[943] ? i[1099] : i[1102]; -assign o[512] = i[943] ? i[1130] : i[512]; -assign o[745] = i[943] ? i[674] : i[745]; -assign o[114] = i[943] ? i[1402] : i[114]; -assign o[897] = i[943] ? i[1211] : i[897]; -assign o[265] = i[943] ? i[182] : i[265]; -assign o[1161] = i[710] ? ~i[1380] : i[1161]; -assign o[1528] = i[710] ? i[1215] : i[1528]; -assign o[50] = i[710] ? i[1350] : i[50]; -assign o[1581] = i[710] ? i[1275] : i[1581]; -assign o[1472] = i[710] ? i[827] : i[1472]; -assign o[226] = i[710] ? ~i[968] : i[226]; -assign o[621] = i[943] ? i[1586] : i[621]; -assign o[266] = i[943] ? i[1037] : i[266]; -assign o[1149] = i[710] ? i[1368] : i[1149]; -assign o[1051] = i[943] ? ~i[32] : i[1051]; -assign o[1321] = i[943] ? i[32] : i[1321]; -assign o[1284] = i[943] ? ~i[650] : i[1284]; -assign o[560] = i[943] ? ~i[1327] : i[560]; -assign o[1452] = i[943] ? ~i[698] : i[1452]; -assign o[469] = i[943] ? i[875] : i[469]; -assign o[559] = i[943] ? ~i[1272] : i[559]; -assign o[44] = i[943] ? ~i[1625] : i[44]; -assign o[1606] = i[710] ? i[472] : i[1606]; -assign o[1624] = i[710] ? i[197] : i[1624]; -assign o[88] = i[943] ? i[522] : i[88]; -assign o[982] = i[943] ? ~i[837] : i[982]; -assign o[865] = i[943] ? ~i[89] : i[865]; -assign o[1431] = i[943] ? i[1134] : i[1431]; -assign o[832] = i[943] ? i[586] : i[832]; -assign o[294] = i[943] ? i[14] : i[294]; -assign o[675] = i[710] ? i[330] : i[675]; -assign o[599] = i[710] ? ~i[561] : i[599]; -assign o[1669] = i[943] ? ~i[1591] : i[1669]; -assign o[1690] = i[943] ? ~i[1349] : i[1690]; -assign o[955] = i[943] ? ~i[945] : i[955]; -assign o[698] = i[710] ? i[1290] : i[698]; -assign o[796] = i[943] ? ~i[1358] : i[796]; -assign o[1104] = i[943] ? i[889] : i[1104]; -assign o[1283] = i[943] ? i[340] : i[1283]; -assign o[1008] = i[943] ? i[169] : i[1008]; -assign o[1625] = i[710] ? i[299] : i[1625]; -assign o[222] = i[710] ? ~i[1108] : i[222]; -assign o[1011] = i[943] ? ~i[666] : i[1011]; -assign o[1036] = i[943] ? ~i[1395] : i[1036]; -assign o[598] = i[943] ? i[176] : i[598]; -assign o[820] = i[943] ? i[1657] : i[820]; -assign o[1529] = i[710] ? ~i[1574] : i[1529]; -assign o[95] = i[710] ? ~i[88] : i[95]; -assign o[1131] = i[943] ? i[1352] : i[1131]; -assign o[1418] = i[710] ? ~i[833] : i[1418]; -assign o[197] = i[943] ? i[944] : i[197]; -assign o[562] = i[710] ? ~i[1032] : i[562]; -assign o[509] = i[943] ? ~i[182] : i[509]; -assign o[597] = i[710] ? ~i[799] : i[597]; -assign o[1288] = i[710] ? ~i[1473] : i[1288]; -assign o[792] = i[710] ? i[851] : i[792]; -assign o[1447] = i[710] ? i[262] : i[1447]; -assign o[1537] = i[943] ? ~i[1591] : i[1537]; -assign o[369] = i[943] ? ~i[1393] : i[369]; -assign o[894] = i[943] ? ~i[650] : i[894]; -assign o[829] = i[943] ? ~i[175] : i[829]; -assign o[902] = i[710] ? i[197] : i[902]; -assign o[823] = i[710] ? ~i[1302] : i[823]; -assign o[756] = i[710] ? i[626] : i[756]; -assign o[683] = i[943] ? i[1225] : i[683]; -assign o[1373] = i[943] ? i[188] : i[1373]; -assign o[1132] = i[710] ? i[1087] : i[1132]; -assign o[1607] = i[943] ? ~i[627] : i[1607]; -assign o[1395] = i[710] ? i[854] : i[1395]; -assign o[960] = i[943] ? i[1081] : i[960]; -assign o[614] = i[943] ? ~i[1107] : i[614]; -assign o[848] = i[943] ? i[473] : i[848]; -assign o[223] = i[710] ? i[1215] : i[223]; -assign o[1679] = i[710] ? i[197] : i[1679]; -assign o[116] = i[943] ? ~i[1005] : i[116]; -assign o[459] = i[943] ? i[844] : i[459]; -assign o[164] = i[943] ? i[333] : i[164]; -assign o[1061] = i[943] ? i[207] : i[1061]; -assign o[498] = i[943] ? ~i[175] : i[498]; -assign o[1113] = i[943] ? i[1717] : i[1113]; -assign o[402] = i[710] ? i[187] : i[402]; -assign o[15] = i[943] ? i[474] : i[15]; -assign o[1683] = i[943] ? i[1090] : i[1683]; -assign o[878] = i[943] ? ~i[1338] : i[878]; -assign o[1553] = i[710] ? i[845] : i[1553]; -assign o[323] = i[710] ? i[959] : i[323]; -assign o[729] = i[943] ? i[261] : i[729]; -assign o[1477] = i[943] ? i[604] : i[1477]; -assign o[1450] = i[710] ? ~i[680] : i[1450]; -assign o[1674] = i[710] ? ~i[415] : i[1674]; -assign o[873] = i[710] ? ~i[892] : i[873]; -assign o[170] = i[943] ? i[1117] : i[170]; -assign o[561] = i[943] ? i[29] : i[561]; -assign o[408] = i[943] ? i[1308] : i[408]; -assign o[101] = i[710] ? ~i[982] : i[101]; -assign o[805] = i[943] ? i[779] : i[805]; -assign o[393] = i[943] ? i[1179] : i[393]; -assign o[1570] = i[710] ? i[430] : i[1570]; -assign o[653] = i[710] ? ~i[1438] : i[653]; -assign o[1516] = i[943] ? ~i[1393] : i[1516]; -assign o[1673] = i[943] ? i[1646] : i[1673]; -assign o[443] = i[943] ? i[513] : i[443]; -assign o[785] = i[710] ? ~i[73] : i[785]; -assign o[1527] = i[943] ? i[1347] : i[1527]; -assign o[348] = i[710] ? i[1495] : i[348]; -assign o[1162] = i[943] ? i[272] : i[1162]; -assign o[32] = i[710] ? i[1082] : i[32]; diff --git a/rtl/chip_6502_mux.v b/rtl/chip_6502_mux.v deleted file mode 100644 index c49c573..0000000 --- a/rtl/chip_6502_mux.v +++ /dev/null @@ -1,11 +0,0 @@ - -module MUX #( - parameter N=1 -) ( - output wire o, - input wire i, - input wire [N-1:0] s, - input wire [N-1:0] d); - - assign o = (|s) ? &(d|(~s)) : i; -endmodule diff --git a/rtl/chip_6502_nodes.inc b/rtl/chip_6502_nodes.inc deleted file mode 100644 index bc093d6..0000000 --- a/rtl/chip_6502_nodes.inc +++ /dev/null @@ -1,206 +0,0 @@ -`define NUM_NODES 1725 - -`define NODE_vcc 657 -`define NODE_vss 558 -`define NODE_cp1 710 -`define NODE_cp2 943 - -`define NODE_res 159 -`define NODE_rw 1156 -`define NODE_db0 1005 -`define NODE_db1 82 -`define NODE_db3 650 -`define NODE_db2 945 -`define NODE_db5 175 -`define NODE_db4 1393 -`define NODE_db7 1349 -`define NODE_db6 1591 -`define NODE_ab0 268 -`define NODE_ab1 451 -`define NODE_ab2 1340 -`define NODE_ab3 211 -`define NODE_ab4 435 -`define NODE_ab5 736 -`define NODE_ab6 887 -`define NODE_ab7 1493 -`define NODE_ab8 230 -`define NODE_ab9 148 -`define NODE_ab12 1237 -`define NODE_ab13 349 -`define NODE_ab10 1443 -`define NODE_ab11 399 -`define NODE_ab14 672 -`define NODE_ab15 195 -`define NODE_sync 539 -`define NODE_so 1672 -`define NODE_clk0 1171 -`define NODE_clk1out 1163 -`define NODE_clk2out 421 -`define NODE_rdy 89 -`define NODE_nmi 1297 -`define NODE_irq 103 - -`define NODE_dpc11_SBADD 549 -`define NODE_dpc9_DBADD 859 - -`define NODE_a0 737 -`define NODE_a1 1234 -`define NODE_a2 978 -`define NODE_a3 162 -`define NODE_a4 727 -`define NODE_a5 858 -`define NODE_a6 1136 -`define NODE_a7 1653 - -`define NODE_y0 64 -`define NODE_y1 1148 -`define NODE_y2 573 -`define NODE_y3 305 -`define NODE_y4 989 -`define NODE_y5 615 -`define NODE_y6 115 -`define NODE_y7 843 - -`define NODE_x0 1216 -`define NODE_x1 98 -`define NODE_x2 1 -`define NODE_x3 1648 -`define NODE_x4 85 -`define NODE_x5 589 -`define NODE_x6 448 -`define NODE_x7 777 - -`define NODE_pcl0 1139 -`define NODE_pcl1 1022 -`define NODE_pcl2 655 -`define NODE_pcl3 1359 -`define NODE_pcl4 900 -`define NODE_pcl5 622 -`define NODE_pcl6 377 -`define NODE_pcl7 1611 -`define NODE_pch0 1670 -`define NODE_pch1 292 -`define NODE_pch2 502 -`define NODE_pch3 584 -`define NODE_pch4 948 -`define NODE_pch5 49 -`define NODE_pch6 1551 -`define NODE_pch7 205 - -`define NODE_Reset0 67 -`define NODE_C1x5Reset 926 - -`define NODE_idl0 1597 // datapath signal internal data latch (driven output) -`define NODE_idl1 870 -`define NODE_idl2 1066 -`define NODE_idl3 464 -`define NODE_idl4 1306 -`define NODE_idl5 240 -`define NODE_idl6 1116 -`define NODE_idl7 391 - -`define NODE_sb0 54 // datapath bus special bus -`define NODE_sb1 1150 -`define NODE_sb2 1287 -`define NODE_sb3 1188 -`define NODE_sb4 1405 -`define NODE_sb5 166 -`define NODE_sb6 1336 -`define NODE_sb7 1001 - -`define NODE_adl0 413 // internal bus address low -`define NODE_adl1 1282 -`define NODE_adl2 1242 -`define NODE_adl3 684 -`define NODE_adl4 1437 -`define NODE_adl5 1630 -`define NODE_adl6 121 -`define NODE_adl7 1299 - -`define NODE_adh0 407 // internal bus address high -`define NODE_adh1 52 -`define NODE_adh2 1651 -`define NODE_adh3 315 -`define NODE_adh4 1160 -`define NODE_adh5 483 -`define NODE_adh6 13 -`define NODE_adh7 1539 - -`define NODE_idb0 1108 // internal bus data bus -`define NODE_idb1 991 -`define NODE_idb2 1473 -`define NODE_idb3 1302 -`define NODE_idb4 892 -`define NODE_idb5 1503 -`define NODE_idb6 833 -`define NODE_idb7 493 - -`define NODE_abl0 1096 // internal bus address bus low latched data out (inverse of inverted storage node) -`define NODE_abl1 376 -`define NODE_abl2 1502 -`define NODE_abl3 1250 -`define NODE_abl4 1232 -`define NODE_abl5 234 -`define NODE_abl6 178 -`define NODE_abl7 567 - -`define NODE_abh0 1429 // internal bus address bus high latched data out (inverse of inverted storage node) -`define NODE_abh1 713 -`define NODE_abh2 287 -`define NODE_abh3 422 -`define NODE_abh4 1143 -`define NODE_abh5 775 -`define NODE_abh6 997 -`define NODE_abh7 489 - -`define NODE_s0 1403 // machine state stack pointer -`define NODE_s1 183 -`define NODE_s2 81 -`define NODE_s3 1532 -`define NODE_s4 1702 -`define NODE_s5 1098 -`define NODE_s6 1212 -`define NODE_s7 1435 - -`define NODE_ir0 328 // internal state instruction register -`define NODE_ir1 1626 -`define NODE_ir2 1384 -`define NODE_ir3 1576 -`define NODE_ir4 1112 -`define NODE_ir5 1329 // ir5 distinguishes branch set from branch clear -`define NODE_ir6 337 -`define NODE_ir7 1328 - -`define NODE_clock1 1536 // internal state timing control aka #T0 -`define NODE_clock2 156 // internal state timing control aka #T+ -`define NODE_t2 971 // internal state timing control -`define NODE_t3 1567 -`define NODE_t4 690 -`define NODE_t5 909 - -`define NODE_alu0 401 -`define NODE_alu1 872 -`define NODE_alu2 1637 -`define NODE_alu3 1414 -`define NODE_alu4 606 -`define NODE_alu5 314 -`define NODE_alu6 331 -`define NODE_alu7 765 - -`define NODE_alua0 1167 -`define NODE_alua1 1248 -`define NODE_alua2 1332 -`define NODE_alua3 1680 -`define NODE_alua4 1142 -`define NODE_alua5 530 -`define NODE_alua6 1627 -`define NODE_alua7 1522 - -`define NODE_alub0 977 -`define NODE_alub1 1432 -`define NODE_alub2 704 -`define NODE_alub3 96 -`define NODE_alub4 1645 -`define NODE_alub5 1678 -`define NODE_alub6 235 -`define NODE_alub7 1535 diff --git a/rtl/cpu/ALU.v b/rtl/cpu/ALU.v new file mode 100644 index 0000000..8d05fc0 --- /dev/null +++ b/rtl/cpu/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/rtl/cpu/cpu.v b/rtl/cpu/cpu.v new file mode 100644 index 0000000..10ad9f5 --- /dev/null +++ b/rtl/cpu/cpu.v @@ -0,0 +1,1228 @@ +/* + * 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 +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) + if ( RDY ) + 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 ( RDY ) + 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 ( RDY ) + 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 ( RDY ) + 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 ( RDY ) + 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 ( RDY ) + 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 ( RDY ) + 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 && RDY ) + 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) + if ( RDY ) + NMI_1 <= NMI; + +always @(posedge clk ) + if ( RDY ) + if( NMI_edge && state == BRK3 ) + NMI_edge <= 0; + else if( NMI & ~NMI_1 ) + NMI_edge <= 1; + +endmodule diff --git a/rtl/led_and_key.v b/rtl/led_and_key.v deleted file mode 100644 index 9216187..0000000 --- a/rtl/led_and_key.v +++ /dev/null @@ -1,164 +0,0 @@ -module ledAndKey( - input clk, - input rst, - - input [3:0] display, - input [7:0] digit1, - input [7:0] digit2, - input [7:0] digit3, - input [7:0] digit4, - input [7:0] digit5, - input [7:0] digit6, - input [7:0] digit7, - input [7:0] digit8, - input [7:0] leds, - - output reg [7:0] keys, - - output reg tm_cs, - output tm_clk, - inout tm_dio -); - - localparam - HIGH = 1'b1, - LOW = 1'b0; - - localparam [7:0] - C_READ = 8'b01000010, - C_WRITE = 8'b01000000, - C_DISP = 8'b10001111, - C_ADDR = 8'b11000000; - - reg counter; - reg [5:0] instruction_step; - - // set up tristate IO pin for display - // tm_dio is physical pin - // dio_in for reading from display - // dio_out for sending to display - // tm_rw selects input or output - reg tm_rw; - wire dio_in, dio_out; - SB_IO #( - .PIN_TYPE(6'b101001), - .PULLUP(1'b1) - ) tm_dio_io ( - .PACKAGE_PIN(tm_dio), - .OUTPUT_ENABLE(tm_rw), - .D_IN_0(dio_in), - .D_OUT_0(dio_out) - ); - - // setup tm1638 module with it's tristate IO - // tm_in is read from module - // tm_out is written to module - // tm_latch triggers the module to read/write display - // tm_rw selects read or write mode to display - // busy indicates when module is busy - // (another latch will interrupt) - // tm_clk is the data clk - // dio_in for reading from display - // dio_out for sending to display - // - // tm_data the tristate io pin to module - reg tm_latch; - wire busy; - wire [7:0] tm_data, tm_in; - reg [7:0] tm_out; - - assign tm_in = tm_data; - assign tm_data = tm_rw ? tm_out : 8'hZZ; - - tm1638 u_tm1638 ( - .clk(clk), - .rst(rst), - .data_latch(tm_latch), - .data(tm_data), - .rw(tm_rw), - .busy(busy), - .sclk(tm_clk), - .dio_in(dio_in), - .dio_out(dio_out) - ); - - always @(posedge clk) begin - if (rst) begin - instruction_step <= 6'b0; - tm_cs <= HIGH; - tm_rw <= HIGH; - - counter <= 1'b0; - keys <= 8'b0; - - end else begin - if (counter && ~busy) begin - case (instruction_step) - // *** KEYS *** - 1: {tm_cs, tm_rw} <= {LOW, HIGH}; - 2: {tm_latch, tm_out} <= {HIGH, C_READ}; // read mode - 3: {tm_latch, tm_rw} <= {HIGH, LOW}; - - // read back keys S1 - S8 - 4: {keys[7], keys[3]} <= {tm_in[0], tm_in[4]}; - 5: {tm_latch} <= {HIGH}; - 6: {keys[6], keys[2]} <= {tm_in[0], tm_in[4]}; - 7: {tm_latch} <= {HIGH}; - 8: {keys[5], keys[1]} <= {tm_in[0], tm_in[4]}; - 9: {tm_latch} <= {HIGH}; - 10: {keys[4], keys[0]} <= {tm_in[0], tm_in[4]}; - 11: {tm_cs} <= {HIGH}; - - // *** DISPLAY *** - 12: {tm_cs, tm_rw} <= {LOW, HIGH}; - 13: {tm_latch, tm_out} <= {HIGH, C_WRITE}; // write mode - 14: {tm_cs} <= {HIGH}; - - 15: {tm_cs, tm_rw} <= {LOW, HIGH}; - 16: {tm_latch, tm_out} <= {HIGH, C_ADDR}; // set addr 0 pos - - 17: {tm_latch, tm_out} <= {HIGH, digit1}; // Digit 1 - 18: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[7]}}; // LED 1 - - 19: {tm_latch, tm_out} <= {HIGH, digit2}; // Digit 2 - 20: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[6]}}; // LED 2 - - 21: {tm_latch, tm_out} <= {HIGH, digit3}; // Digit 3 - 22: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[5]}}; // LED 3 - - 23: {tm_latch, tm_out} <= {HIGH, digit4}; // Digit 4 - 24: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[4]}}; // LED 4 - - 25: {tm_latch, tm_out} <= {HIGH, digit5}; // Digit 5 - 26: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[3]}}; // LED 5 - - 27: {tm_latch, tm_out} <= {HIGH, digit6}; // Digit 6 - 28: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[2]}}; // LED 6 - - 29: {tm_latch, tm_out} <= {HIGH, digit7}; // Digit 7 - 30: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[1]}}; // LED 7 - - 31: {tm_latch, tm_out} <= {HIGH, digit8}; // Digit 8 - 32: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[0]}}; // LED 8 - - 33: {tm_cs} <= {HIGH}; - - 34: {tm_cs, tm_rw} <= {LOW, HIGH}; - 35: {tm_latch, tm_out} <= {HIGH, {4'b1000, display}}; // display - 36: {tm_cs, instruction_step} <= {HIGH, 6'b0}; - - endcase - - instruction_step <= instruction_step + 1; - - end else if (busy) begin - // pull latch low next clock cycle after module has been - // latched - tm_latch <= LOW; - end - - counter <= ~counter; - end - end -endmodule - diff --git a/rtl/led_and_key/led_and_key.v b/rtl/led_and_key/led_and_key.v new file mode 100644 index 0000000..911ab7d --- /dev/null +++ b/rtl/led_and_key/led_and_key.v @@ -0,0 +1,167 @@ +module ledAndKey( + input clk, + input clk_en, + input rst, + + input [3:0] display, + input [7:0] digit1, + input [7:0] digit2, + input [7:0] digit3, + input [7:0] digit4, + input [7:0] digit5, + input [7:0] digit6, + input [7:0] digit7, + input [7:0] digit8, + input [7:0] leds, + + output reg [7:0] keys, + + output reg tm_cs, + output tm_clk, + inout tm_dio +); + + localparam + HIGH = 1'b1, + LOW = 1'b0; + + localparam [7:0] + C_READ = 8'b01000010, + C_WRITE = 8'b01000000, + C_DISP = 8'b10001111, + C_ADDR = 8'b11000000; + + reg counter; + reg [5:0] instruction_step; + + // set up tristate IO pin for display + // tm_dio is physical pin + // dio_in for reading from display + // dio_out for sending to display + // tm_rw selects input or output + reg tm_rw; + wire dio_in, dio_out; + SB_IO #( + .PIN_TYPE(6'b101001), + .PULLUP(1'b1) + ) tm_dio_io ( + .PACKAGE_PIN(tm_dio), + .OUTPUT_ENABLE(tm_rw), + .D_IN_0(dio_in), + .D_OUT_0(dio_out) + ); + + // setup tm1638 module with it's tristate IO + // tm_in is read from module + // tm_out is written to module + // tm_latch triggers the module to read/write display + // tm_rw selects read or write mode to display + // busy indicates when module is busy + // (another latch will interrupt) + // tm_clk is the data clk + // dio_in for reading from display + // dio_out for sending to display + // + // tm_data the tristate io pin to module + reg tm_latch; + wire busy; + wire [7:0] tm_data, tm_in; + reg [7:0] tm_out; + + assign tm_in = tm_data; + assign tm_data = tm_rw ? tm_out : 8'hZZ; + + tm1638 u_tm1638 ( + .clk(clk), + .clk_en(clk_en), + .rst(rst), + .data_latch(tm_latch), + .data(tm_data), + .rw(tm_rw), + .busy(busy), + .sclk(tm_clk), + .dio_in(dio_in), + .dio_out(dio_out) + ); + + always @(posedge clk) begin + if (clk_en) begin + if (rst) begin + instruction_step <= 6'b0; + tm_cs <= HIGH; + tm_rw <= HIGH; + + counter <= 1'b0; + keys <= 8'b0; + + end else begin + if (counter && ~busy) begin + case (instruction_step) + // *** KEYS *** + 1: {tm_cs, tm_rw} <= {LOW, HIGH}; + 2: {tm_latch, tm_out} <= {HIGH, C_READ}; // read mode + 3: {tm_latch, tm_rw} <= {HIGH, LOW}; + + // read back keys S1 - S8 + 4: {keys[7], keys[3]} <= {tm_in[0], tm_in[4]}; + 5: {tm_latch} <= {HIGH}; + 6: {keys[6], keys[2]} <= {tm_in[0], tm_in[4]}; + 7: {tm_latch} <= {HIGH}; + 8: {keys[5], keys[1]} <= {tm_in[0], tm_in[4]}; + 9: {tm_latch} <= {HIGH}; + 10: {keys[4], keys[0]} <= {tm_in[0], tm_in[4]}; + 11: {tm_cs} <= {HIGH}; + + // *** DISPLAY *** + 12: {tm_cs, tm_rw} <= {LOW, HIGH}; + 13: {tm_latch, tm_out} <= {HIGH, C_WRITE}; // write mode + 14: {tm_cs} <= {HIGH}; + + 15: {tm_cs, tm_rw} <= {LOW, HIGH}; + 16: {tm_latch, tm_out} <= {HIGH, C_ADDR}; // set addr 0 pos + + 17: {tm_latch, tm_out} <= {HIGH, digit1}; // Digit 1 + 18: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[7]}}; // LED 1 + + 19: {tm_latch, tm_out} <= {HIGH, digit2}; // Digit 2 + 20: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[6]}}; // LED 2 + + 21: {tm_latch, tm_out} <= {HIGH, digit3}; // Digit 3 + 22: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[5]}}; // LED 3 + + 23: {tm_latch, tm_out} <= {HIGH, digit4}; // Digit 4 + 24: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[4]}}; // LED 4 + + 25: {tm_latch, tm_out} <= {HIGH, digit5}; // Digit 5 + 26: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[3]}}; // LED 5 + + 27: {tm_latch, tm_out} <= {HIGH, digit6}; // Digit 6 + 28: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[2]}}; // LED 6 + + 29: {tm_latch, tm_out} <= {HIGH, digit7}; // Digit 7 + 30: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[1]}}; // LED 7 + + 31: {tm_latch, tm_out} <= {HIGH, digit8}; // Digit 8 + 32: {tm_latch, tm_out} <= {HIGH, {7'b0, leds[0]}}; // LED 8 + + 33: {tm_cs} <= {HIGH}; + + 34: {tm_cs, tm_rw} <= {LOW, HIGH}; + 35: {tm_latch, tm_out} <= {HIGH, {4'b1000, display}}; // display + 36: {tm_cs, instruction_step} <= {HIGH, 6'b0}; + + endcase + + instruction_step <= instruction_step + 1; + + end else if (busy) begin + // pull latch low next clock cycle after module has been + // latched + tm_latch <= LOW; + end + + counter <= ~counter; + end + end + end +endmodule diff --git a/rtl/tm1638.v b/rtl/led_and_key/tm1638.v similarity index 82% rename from rtl/tm1638.v rename to rtl/led_and_key/tm1638.v index 1e6aa95..b40c5f1 100644 --- a/rtl/tm1638.v +++ b/rtl/led_and_key/tm1638.v @@ -1,5 +1,6 @@ module tm1638( input clk, + input clk_en, input rst, input data_latch, @@ -96,23 +97,26 @@ module tm1638( always @(posedge clk) begin - if (rst) + if (clk_en) begin - cur_state <= S_IDLE; - sclk_q <= 0; - ctr_q <= 0; - dio_out <= 0; - data_q <= 0; - data_out_q <= 0; - end - else - begin - cur_state <= next_state; - sclk_q <= sclk_d; - ctr_q <= ctr_d; - dio_out <= dio_out_d; - data_q <= data_d; - data_out_q <= data_out_d; + if (rst) + begin + cur_state <= S_IDLE; + sclk_q <= 0; + ctr_q <= 0; + dio_out <= 0; + data_q <= 0; + data_out_q <= 0; + end + else + begin + cur_state <= next_state; + sclk_q <= sclk_d; + ctr_q <= ctr_d; + dio_out <= dio_out_d; + data_q <= data_d; + data_out_q <= data_out_d; + end end end -endmodule \ No newline at end of file +endmodule diff --git a/rtl/ram.v b/rtl/ram.v new file mode 100644 index 0000000..3f19620 --- /dev/null +++ b/rtl/ram.v @@ -0,0 +1,22 @@ +module ram( + input clk, + input [12:0] address, + input w_en, + input [7:0] din, + output reg [7:0] dout + ); + + /* synthesis syn_ramstyle = rw_check */ + reg [7:0] ram[0:8191]; + + initial + $readmemh("../../../roms/ram.hex", ram, 0, 8191); + + always @(posedge clk) + begin + dout <= ram[address]; + if (w_en) ram[address] <= din; + end + +endmodule + diff --git a/rtl/rom_wozmon.v b/rtl/rom_wozmon.v new file mode 100644 index 0000000..c29bf8f --- /dev/null +++ b/rtl/rom_wozmon.v @@ -0,0 +1,19 @@ +module rom_wozmon( + input clk, + input [7:0] address, + output reg [7:0] dout + ); + + reg [7:0] rom[0:255]; + + initial + $readmemh("../../../roms/rom.hex", rom, 0, 255); + + always @(posedge clk) + begin + dout <= rom[address]; + end + +endmodule + + diff --git a/rtl/uart.v b/rtl/uart.v deleted file mode 100644 index 9f22421..0000000 --- a/rtl/uart.v +++ /dev/null @@ -1,212 +0,0 @@ -// Documented Verilog UART -// Copyright (C) 2010 Timothy Goddard (tim@goddard.net.nz) -// Distributed under the MIT licence. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -module uart( - input clk, // The master clock for this module - input rst, // Synchronous reset. - input rx, // Incoming serial line - output tx, // Outgoing serial line - input transmit, // Signal to transmit - input [7:0] tx_byte, // Byte to transmit - output received, // Indicated that a byte has been received. - output [7:0] rx_byte, // Byte received - output is_receiving, // Low when receive line is idle. - output is_transmitting, // Low when transmit line is idle. - output recv_error // Indicates error in receiving packet. - ); - -parameter CLOCK_DIVIDE = 1302; // clock rate (50Mhz) / (baud rate (9600) * 4) - -// States for the receiving state machine. -// These are just constants, not parameters to override. -parameter RX_IDLE = 0; -parameter RX_CHECK_START = 1; -parameter RX_READ_BITS = 2; -parameter RX_CHECK_STOP = 3; -parameter RX_DELAY_RESTART = 4; -parameter RX_ERROR = 5; -parameter RX_RECEIVED = 6; - -// States for the transmitting state machine. -// Constants - do not override. -parameter TX_IDLE = 0; -parameter TX_SENDING = 1; -parameter TX_DELAY_RESTART = 2; - -reg [10:0] rx_clk_divider = CLOCK_DIVIDE; -reg [10:0] tx_clk_divider = CLOCK_DIVIDE; - -reg [2:0] recv_state = RX_IDLE; -reg [5:0] rx_countdown; -reg [3:0] rx_bits_remaining; -reg [7:0] rx_data; - -reg tx_out = 1'b1; -reg [1:0] tx_state = TX_IDLE; -reg [5:0] tx_countdown; -reg [3:0] tx_bits_remaining; -reg [7:0] tx_data; - -assign received = recv_state == RX_RECEIVED; -assign recv_error = recv_state == RX_ERROR; -assign is_receiving = recv_state != RX_IDLE; -assign rx_byte = rx_data; - -assign tx = tx_out; -assign is_transmitting = tx_state != TX_IDLE; - -always @(posedge clk) begin - if (rst) begin - recv_state = RX_IDLE; - tx_state = TX_IDLE; - end - - // The clk_divider counter counts down from - // the CLOCK_DIVIDE constant. Whenever it - // reaches 0, 1/16 of the bit period has elapsed. - // Countdown timers for the receiving and transmitting - // state machines are decremented. - rx_clk_divider = rx_clk_divider - 1; - if (!rx_clk_divider) begin - rx_clk_divider = CLOCK_DIVIDE; - rx_countdown = rx_countdown - 1; - end - tx_clk_divider = tx_clk_divider - 1; - if (!tx_clk_divider) begin - tx_clk_divider = CLOCK_DIVIDE; - tx_countdown = tx_countdown - 1; - end - - // Receive state machine - case (recv_state) - RX_IDLE: begin - // A low pulse on the receive line indicates the - // start of data. - if (!rx) begin - // Wait half the period - should resume in the - // middle of this first pulse. - rx_clk_divider = CLOCK_DIVIDE; - rx_countdown = 2; - recv_state = RX_CHECK_START; - end - end - RX_CHECK_START: begin - if (!rx_countdown) begin - // Check the pulse is still there - if (!rx) begin - // Pulse still there - good - // Wait the bit period to resume half-way - // through the first bit. - rx_countdown = 4; - rx_bits_remaining = 8; - recv_state = RX_READ_BITS; - end else begin - // Pulse lasted less than half the period - - // not a valid transmission. - recv_state = RX_ERROR; - end - end - end - RX_READ_BITS: begin - if (!rx_countdown) begin - // Should be half-way through a bit pulse here. - // Read this bit in, wait for the next if we - // have more to get. - rx_data = {rx, rx_data[7:1]}; - rx_countdown = 4; - rx_bits_remaining = rx_bits_remaining - 1; - recv_state = rx_bits_remaining ? RX_READ_BITS : RX_CHECK_STOP; - end - end - RX_CHECK_STOP: begin - if (!rx_countdown) begin - // Should resume half-way through the stop bit - // This should be high - if not, reject the - // transmission and signal an error. - recv_state = rx ? RX_RECEIVED : RX_ERROR; - end - end - RX_DELAY_RESTART: begin - // Waits a set number of cycles before accepting - // another transmission. - recv_state = rx_countdown ? RX_DELAY_RESTART : RX_IDLE; - end - RX_ERROR: begin - // There was an error receiving. - // Raises the recv_error flag for one clock - // cycle while in this state and then waits - // 2 bit periods before accepting another - // transmission. - rx_countdown = 8; - recv_state = RX_DELAY_RESTART; - end - RX_RECEIVED: begin - // Successfully received a byte. - // Raises the received flag for one clock - // cycle while in this state. - recv_state = RX_IDLE; - end - endcase - - // Transmit state machine - case (tx_state) - TX_IDLE: begin - if (transmit) begin - // If the transmit flag is raised in the idle - // state, start transmitting the current content - // of the tx_byte input. - tx_data = tx_byte; - // Send the initial, low pulse of 1 bit period - // to signal the start, followed by the data - tx_clk_divider = CLOCK_DIVIDE; - tx_countdown = 4; - tx_out = 0; - tx_bits_remaining = 8; - tx_state = TX_SENDING; - end - end - TX_SENDING: begin - if (!tx_countdown) begin - if (tx_bits_remaining) begin - tx_bits_remaining = tx_bits_remaining - 1; - tx_out = tx_data[0]; - tx_data = {1'b0, tx_data[7:1]}; - tx_countdown = 4; - tx_state = TX_SENDING; - end else begin - // Set delay to send out 2 stop bits. - tx_out = 1; - tx_countdown = 8; - tx_state = TX_DELAY_RESTART; - end - end - end - TX_DELAY_RESTART: begin - // Wait until tx_countdown reaches the end before - // we send another transmission. This covers the - // "stop bit" delay. - tx_state = tx_countdown ? TX_DELAY_RESTART : TX_IDLE; - end - endcase -end - -endmodule diff --git a/rtl/uart/async_tx_rx.v b/rtl/uart/async_tx_rx.v new file mode 100644 index 0000000..90f0349 --- /dev/null +++ b/rtl/uart/async_tx_rx.v @@ -0,0 +1,176 @@ +//////////////////////////////////////////////////////// +// RS-232 RX and TX module +// (c) fpga4fun.com & KNJN LLC - 2003 to 2016 + +// The RS-232 settings are fixed +// TX: 8-bit data, 2 stop, no-parity +// RX: 8-bit data, 1 stop, no-parity (the receiver can accept more stop bits of course) + +//////////////////////////////////////////////////////// +module async_transmitter( + input clk, + input TxD_start, + input [7:0] TxD_data, + output TxD, + output TxD_busy + ); + + // Assert TxD_start for (at least) one clock cycle to start transmission of TxD_data + // TxD_data is latched so that it doesn't have to stay valid while it is being sent + + parameter ClkFrequency = 25000000; // 25MHz + parameter Baud = 115200; + + //////////////////////////////// + wire BitTick; + BaudTickGen #(ClkFrequency, Baud) tickgen(.clk(clk), .enable(TxD_busy), .tick(BitTick)); + + reg [3:0] TxD_state; + reg [7:0] TxD_shift; + + wire TxD_ready = (TxD_state==0); + assign TxD_busy = ~TxD_ready; + + always @(posedge clk) + begin + if(TxD_ready & TxD_start) + TxD_shift <= TxD_data; + else + if(TxD_state[3] & BitTick) + TxD_shift <= (TxD_shift >> 1); + + case(TxD_state) + 4'b0000: if(TxD_start) TxD_state <= 4'b0100; + 4'b0100: if(BitTick) TxD_state <= 4'b1000; // start bit + 4'b1000: if(BitTick) TxD_state <= 4'b1001; // bit 0 + 4'b1001: if(BitTick) TxD_state <= 4'b1010; // bit 1 + 4'b1010: if(BitTick) TxD_state <= 4'b1011; // bit 2 + 4'b1011: if(BitTick) TxD_state <= 4'b1100; // bit 3 + 4'b1100: if(BitTick) TxD_state <= 4'b1101; // bit 4 + 4'b1101: if(BitTick) TxD_state <= 4'b1110; // bit 5 + 4'b1110: if(BitTick) TxD_state <= 4'b1111; // bit 6 + 4'b1111: if(BitTick) TxD_state <= 4'b0010; // bit 7 + 4'b0010: if(BitTick) TxD_state <= 4'b0011; // stop1 + 4'b0011: if(BitTick) TxD_state <= 4'b0000; // stop2 + default: if(BitTick) TxD_state <= 4'b0000; + endcase + end + + assign TxD = (TxD_state<4) | (TxD_state[3] & TxD_shift[0]); +endmodule + + +//////////////////////////////////////////////////////// +module async_receiver( + input clk, + input RxD, + output reg RxD_data_ready, + output reg [7:0] RxD_data, // data received, valid only (for one clock cycle) when RxD_data_ready is asserted + + // We also detect if a gap occurs in the received stream of characters + // That can be useful if multiple characters are sent in burst + // so that multiple characters can be treated as a "packet" + output RxD_idle, // asserted when no data has been received for a while + output reg RxD_endofpacket = 0 // asserted for one clock cycle when a packet has been detected (i.e. RxD_idle is going high) + ); + + parameter ClkFrequency = 25000000; // 12MHz + parameter Baud = 115200; + + parameter Oversampling = 8; // needs to be a power of 2 + // we oversample the RxD line at a fixed rate to capture each RxD data bit at the "right" time + // 8 times oversampling by default, use 16 for higher quality reception + + //////////////////////////////// + reg [3:0] RxD_state; + + wire OversamplingTick; + BaudTickGen #(ClkFrequency, Baud, Oversampling) tickgen(.clk(clk), .enable(1'b1), .tick(OversamplingTick)); + + // synchronize RxD to our clk domain + reg [1:0] RxD_sync; // 2'b11 + always @(posedge clk) if(OversamplingTick) RxD_sync <= {RxD_sync[0], RxD}; + + // and filter it + reg [1:0] Filter_cnt; // 2'b11 + reg RxD_bit; // 1'b1 + always @(posedge clk) + if(OversamplingTick) + begin + if(RxD_sync[1]==1'b1 && Filter_cnt!=2'b11) Filter_cnt <= Filter_cnt + 1'd1; + else if(RxD_sync[1]==1'b0 && Filter_cnt!=2'b00) Filter_cnt <= Filter_cnt - 1'd1; + + if(Filter_cnt==2'b11) RxD_bit <= 1'b1; + else if(Filter_cnt==2'b00) RxD_bit <= 1'b0; + end + + // and decide when is the good time to sample the RxD line + function integer log2(input integer v); + begin + log2=0; + while(v>>log2) + log2 = log2 + 1; + end + endfunction + + localparam l2o = log2(Oversampling); + reg [l2o-2:0] OversamplingCnt; + + always @(posedge clk) + if(OversamplingTick) OversamplingCnt <= (RxD_state==0) ? 1'd0 : OversamplingCnt + 1'd1; + + wire sampleNow = OversamplingTick && (OversamplingCnt==Oversampling/2-1); + + // now we can accumulate the RxD bits in a shift-register + always @(posedge clk) + case(RxD_state) + 4'b0000: if(~RxD_bit) RxD_state <= 4'b0001; // start bit found? + 4'b0001: if(sampleNow) RxD_state <= 4'b1000; // sync start bit to sampleNow + 4'b1000: if(sampleNow) RxD_state <= 4'b1001; // bit 0 + 4'b1001: if(sampleNow) RxD_state <= 4'b1010; // bit 1 + 4'b1010: if(sampleNow) RxD_state <= 4'b1011; // bit 2 + 4'b1011: if(sampleNow) RxD_state <= 4'b1100; // bit 3 + 4'b1100: if(sampleNow) RxD_state <= 4'b1101; // bit 4 + 4'b1101: if(sampleNow) RxD_state <= 4'b1110; // bit 5 + 4'b1110: if(sampleNow) RxD_state <= 4'b1111; // bit 6 + 4'b1111: if(sampleNow) RxD_state <= 4'b0010; // bit 7 + 4'b0010: if(sampleNow) RxD_state <= 4'b0000; // stop bit + default: RxD_state <= 4'b0000; + endcase + + always @(posedge clk) + if (sampleNow && RxD_state[3]) RxD_data <= {RxD_bit, RxD_data[7:1]}; + always @(posedge clk) + RxD_data_ready <= (sampleNow && RxD_state==4'b0010 && RxD_bit); // make sure a stop bit is received + + reg [l2o+1:0] GapCnt; + always @(posedge clk) + if (RxD_state!=0) GapCnt<=0; else if(OversamplingTick & ~GapCnt[log2(Oversampling)+1]) GapCnt <= GapCnt + 1'h1; + + assign RxD_idle = GapCnt[l2o+1]; + always @(posedge clk) + RxD_endofpacket <= OversamplingTick & ~GapCnt[l2o+1] & &GapCnt[l2o:0]; + +endmodule + +//////////////////////////////////////////////////////// +module BaudTickGen( + input clk, enable, + output tick // generate a tick at the specified baud rate * oversampling + ); + + parameter ClkFrequency = 25000000; + parameter Baud = 115200; + parameter Oversampling = 1; + + function integer log2(input integer v); begin log2=0; while(v>>log2) log2=log2+1; end endfunction + + localparam AccWidth = log2(ClkFrequency/Baud)+8; // +/- 2% max timing error over a byte + reg [AccWidth:0] Acc; + localparam ShiftLimiter = log2(Baud*Oversampling >> (31-AccWidth)); // this makes sure Inc calculation doesn't overflow + localparam Inc = ((Baud*Oversampling << (AccWidth-ShiftLimiter))+(ClkFrequency>>(ShiftLimiter+1)))/(ClkFrequency>>ShiftLimiter); + + always @(posedge clk) if(enable) Acc <= Acc[AccWidth-1:0] + Inc[AccWidth:0]; else Acc <= Inc[AccWidth:0]; + assign tick = Acc[AccWidth]; + +endmodule diff --git a/rtl/uart/uart.v b/rtl/uart/uart.v new file mode 100644 index 0000000..8ff643f --- /dev/null +++ b/rtl/uart/uart.v @@ -0,0 +1,118 @@ +`include "./async_tx_rx.v" + +module uart( + input clk, + + input enable, + input [1:0] address, + input w_en, + input [7:0] din, + output reg [7:0] dout, + + input uart_rx, + output uart_tx, + output uart_cts, + output reg [7:0] led + ); + + parameter ClkFrequency = 25000000; // 25MHz + parameter Baud = 115200; + parameter Oversampling = 8; + + reg uart_tx_stb; + reg [7:0] uart_tx_byte; + wire uart_tx_status; + + async_transmitter #(ClkFrequency, Baud) my_tx ( + .clk(clk), + .TxD_start(uart_tx_stb), + .TxD_data(uart_tx_byte), + .TxD(uart_tx), + .TxD_busy(uart_tx_status) + ); + + wire uart_rx_stb, rx_idle, rx_end; + wire [7:0] rx_data; + reg uart_rx_status, uart_rx_ack; + reg [7:0] uart_rx_byte; + + async_receiver #(ClkFrequency, Baud, Oversampling) my_rx( + .clk(clk), + .RxD(uart_rx), + .RxD_data_ready(uart_rx_stb), + .RxD_data(rx_data), + .RxD_idle(rx_idle), + .RxD_endofpacket(rx_end) + ); + + always @(posedge clk) + begin + // new byte from RX, check register is clear and CPU has seen + // previous byte, otherwise we ignore the new data + if (uart_rx_stb && ~uart_rx_status) + begin + uart_rx_status <= 'b1; + uart_rx_byte <= rx_data; + end + + // clear the rx status flag on ack from CPU + if (uart_rx_ack) + uart_rx_status <= 'b0; + end + + assign uart_cts = ~rx_idle || uart_rx_status; + + localparam UART_RX = 2'b00; + localparam UART_RXCR = 2'b01; + localparam UART_TX = 2'b10; + + // Handle Register + always @(posedge clk) + begin + uart_tx_stb <= 0; + uart_rx_ack <= 0; + + led[7] <= uart_rx_status; + + if (enable) + begin + case (address) + + UART_TX: + begin + // UART TX - 0xD012 + if (w_en) + begin + // Apple 1 terminal only uses 7 bits, MSB indicates + // terminal has ack'd RX + if (~uart_tx_status) + begin + uart_tx_byte <= {1'b0, din[6:0]}; + uart_tx_stb <= 1; + end + end + else + dout <= {uart_tx_status, 7'd0}; + end + + UART_RXCR: + begin + // UART RX CR - 0xD011 + if (~w_en) + dout <= {uart_rx_status, 7'b0}; + end + + UART_RX: + begin + // UART RX - 0xD010 + if (~w_en) + begin + dout <= {uart_rx_status, uart_rx_byte[6:0]}; + uart_rx_ack <= 1'b1; + led[6:0] <= uart_rx_byte[6:0]; + end + end + endcase + end + end +endmodule diff --git a/rtl/vga/vga.v b/rtl/vga/vga.v new file mode 100644 index 0000000..73b1c09 --- /dev/null +++ b/rtl/vga/vga.v @@ -0,0 +1,144 @@ +module vga( + input clk, + input [6:0] in, + input in_stb, + output vga_h_sync, + output vga_v_sync, + output reg vga_red, + output reg vga_grn, + output reg vga_blu + ); + + reg [5:0] v_ram[0:959] /* synthesis syn_ramstyle = "block_ram" */; + reg [4:0] c_rom[0:447] /* synthesis syn_ramstyle = "block_ram" */; + initial begin + $readmemb("../roms/vga_vram.bin", v_ram, 0, 959); + $readmemb("../roms/vga_font.bin", c_rom, 0, 447); + end + + // generate 25MHz pixel clock enable + reg vga_cnt; + wire vga_clk_en; + + always @(posedge clk) + begin + vga_cnt <= vga_cnt + 1; + end + assign vga_clk_en = vga_cnt; + + // video structure constants + parameter hpixels = 800; // horizontal pixels per line + parameter vlines = 521; // vertical lines per frame + parameter hpulse = 96; // hsync pulse length + parameter vpulse = 2; // vsync pulse length + parameter hbp = 144; // end of horizontal back porch + parameter hfp = 784; // beginning of horizontal front porch + parameter vbp = 31; // end of vertical back porch + parameter vfp = 511; // beginning of vertical front porch + + // registers for storing the horizontal & vertical counters + reg [9:0] hc; + reg [9:0] vc; + reg [5:0] hpos; + reg [4:0] vpos; + reg [3:0] hdot; + reg [4:0] vdot; + + always @(posedge clk) + begin + if (vga_clk_en) + begin + if (hc < hpixels - 1) + begin + hc <= hc + 1; + + // count 16 pixels, so 640px / 16 = 40 characters + if (vga_h_act) + begin + hdot <= hdot + 1; + + if (hdot == 4'hF) + begin + hdot <= 0; + hpos <= hpos + 1; + end + end + end + else + begin + // reset horizontal counters + hc <= 0; + hdot <= 0; + hpos <= 0; + + if (vc < vlines - 1) + begin + vc <= vc + 1; + + // count 20 rows, so 480px / 20 = 24 rows + if (vga_v_act) + begin + vdot <= vdot + 1; + + if (vdot == 5'd19) + begin + vdot <= 0; + vpos <= vpos + 1; + end + end + end + else + begin + vc <= 0; + vdot <= 0; + vpos <= 0; + end + end + end + end + + assign vga_h_act = (hc >= hbp && hc < hfp); + assign vga_v_act = (vc >= vbp && vc < vfp); + + assign vga_h_sync = (hc < hpulse) ? 0 : 1; + assign vga_v_sync = (vc < vpulse) ? 0 : 1; + // assign vblank = (vc >= vbp && vc < vfp) ? 0:1; + + always @(posedge clk) + begin + if (~(vga_h_act && vga_v_act)) + begin + // outside display area + vga_red = 0; + + end else begin + // inside display area + + if (vdot[4:1] == 0 || vdot[4:1] == 1 || vdot[4:1] == 9 || hdot[3:1] == 0 || hdot[3:1] == 6 || hdot[3:1] == 7) + vga_red = 0; + else + vga_red = c_rom[(v_ram[hpos + (vpos * 40)] * 7) + (vdot[4:1] - 2)][5 - hdot[3:1]]; + + end + + vga_grn = vga_red; + vga_blu = vga_red; + end + + reg [5:0] cur_pos; + reg stb; + always @(posedge clk) + begin + if (in_stb & ~stb) + begin + v_ram[cur_pos] <= {~in[6], in[4:0]}; + stb <= 1; + cur_pos <= cur_pos + 1; + end + + if (~in_stb & stb) + begin + stb <= 0; + end + end +endmodule