--- /dev/null
+/_ngo
+/bitgen.xmsgs
+/map.xmsgs
+/ngdbuild.xmsgs
+/par.xmsgs
+/trce.xmsgs
+/xst.xmsgs
+/core.bld
+/core.cmd_log
+/core.lso
+/core.ngc
+/core.ngd
+/core.ngr
+/core.prj
+/core.stx
+/core.syr
+/core.xst
+/core_map.map
+/core_map.mrp
+/core_ngdbuild.xrpt
+/core_summary.html
+/core_xst.xrpt
+/main.bgn
+/main.bld
+/main.cmd_log
+/main.drc
+/main.lso
+/main.mcs
+/main.ncd
+/main.ngc
+/main.ngd
+/main.ngr
+/main.pad
+/main.par
+/main.pcf
+/main.prj
+/main.prm
+/main.ptwx
+/main.stx
+/main.syr
+/main.twr
+/main.twx
+/main.unroutes
+/main.ut
+/main.v.cmd_log
+/main.v.prj
+/main.v.stx
+/main.v.syr
+/main.v.xst
+/main.v_summary.html
+/main.v_xst.xrpt
+/main.xpi
+/main.xst
+/main_envsettings.html
+/main_map.map
+/main_map.mrp
+/main_map.ncd
+/main_map.ngm
+/main_map.xrpt
+/main_ngdbuild.xrpt
+/main_pad.csv
+/main_pad.txt
+/main_par.xrpt
+/main_preroute.twr
+/main_preroute.twx
+/main_summary.html
+/main_summary.xml
+/main_usage.xml
+/main_xst.xrpt
+/planAhead_run_1
+/planAhead_run_2
+/usage_statistics_webtalk.html
+/webtalk.log
+/webtalk_pn.xml
+/xlnx_auto_0_xdb
+/xst
+/output.bit
--- /dev/null
+# 32-bit RISC-V processor design
+
+Implements RV32I instruction set except for interrupts and some CSRs.
+
+Warning: CSR and system instructions weren't really tested so may not work properly
+
+Default software runs a 2.5D maze game through the VGA port, using SW2 and SW3 to turn and move.
+
+Implemented CSRs:
+- cycle/cycleh -- doesn't count
+- time/timeh -- doesn't count
+- instret/instreth -- doesn't count
+- mvendorid
+- marchid
+- mimpid
+- misa -- ignores writes
+- mstatus -- all but mpie and mie are hardwired
+- mie -- all but meie, mtie, and msie are hardwired
+- mtvec -- hardwired to 0x10040
+- mscratch
+- mepc
+- mcause
+- mip -- ignores writes
+
+- used FPGA: ChinaQMTECH's QM_XC6SLX16_DDR3 board with the vga output board. [Docs](https://raw.githubusercontent.com/ChinaQMTECH/QM_XC6SLX16_DDR3/master/QM_XC6SLX16_DDR3_V02.zip) [archived on archive.org](http://web.archive.org/web/20180321000346/https://raw.githubusercontent.com/ChinaQMTECH/QM_XC6SLX16_DDR3/master/QM_XC6SLX16_DDR3_V02.zip)
+- used programmer: Digilent's Hs2 JTAG programmer
+
+## Building (On Ubuntu 16.04)
+Requires Xilinx's ISE v. 14.7 to be installed in /opt/Xilinx (just leave the default installation directory)
+
+ sudo apt-get install git g++ autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
+ sudo mkdir /opt/riscv
+ sudo chown $USER /opt/riscv # so you don't need root when building; you can change back after building riscv-gnu-toolchain
+ git clone --recursive https://github.com/riscv/riscv-gnu-toolchain.git
+ export PATH=/opt/riscv/bin:"$PATH"
+ cd riscv-gnu-toolchain
+ ./configure --prefix=/opt/riscv --with-arch=rv32i
+ make
+ sudo chown -R root:root /opt/riscv # change owner back to root as the compiler is finished installing
+ cd ..
+ git clone https://github.com/programmerjake/rv32.git
+ cd rv32/software
+ make
+ cd ..
+ # at this point the built bitstream is in output.bit
+ djtgcfg prog -d JtagHS2 -i 0 -f output.bit # program the FPGA
+
+## Building the hardware (only required if verilog source is modified)
+
+Requires having built the software at least once to generate the ram initialization files.
+
+Run `(. /opt/Xilinx/14.7/ISE_DS/settings64.sh; ise&)` in a terminal.
+Switch the view to Implementation
+Select main.v
+Run "Generate Programming File"
+Open a terminal and run:
+
+ export PATH=/opt/riscv/bin:"$PATH"
+ cd rv32/software
+ make
+ cd ..
+ # at this point the built bitstream is in output.bit
+ djtgcfg prog -d JtagHS2 -i 0 -f output.bit # program the FPGA
+
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 1ps
+
+module block_memory(
+ input clk,
+ input [31:0] a_ram_address,
+ input [3:0] a_write_enable,
+ input [31:0] a_write_input,
+ output reg [31:0] a_read_output,
+ input [31:0] b_ram_address,
+ output reg [31:0] b_read_output
+ );
+
+ wire a_enable_0 = a_ram_address[31:11] == 0;
+ wire b_enable_0 = b_ram_address[31:11] == 0;
+ wire [3:0] a_write_enable_0 = {4{a_enable_0}} & a_write_enable;
+ wire [31:0] a_read_output_0;
+ wire [31:0] b_read_output_0;
+ block_memory_16kbit #(
+ .initial_file("software/ram_0_byte0.hex")
+ ) ram_0_byte0(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_0[0]),
+ .port_a_write_input(a_write_input[7:0]),
+ .port_a_read_output(a_read_output_0[7:0]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_0[7:0])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_0_byte1.hex")
+ ) ram_0_byte1(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_0[1]),
+ .port_a_write_input(a_write_input[15:8]),
+ .port_a_read_output(a_read_output_0[15:8]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_0[15:8])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_0_byte2.hex")
+ ) ram_0_byte2(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_0[2]),
+ .port_a_write_input(a_write_input[23:16]),
+ .port_a_read_output(a_read_output_0[23:16]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_0[23:16])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_0_byte3.hex")
+ ) ram_0_byte3(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_0[3]),
+ .port_a_write_input(a_write_input[31:24]),
+ .port_a_read_output(a_read_output_0[31:24]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_0[31:24])
+ );
+
+
+ wire a_enable_1 = a_ram_address[31:11] == 1;
+ wire b_enable_1 = b_ram_address[31:11] == 1;
+ wire [3:0] a_write_enable_1 = {4{a_enable_1}} & a_write_enable;
+ wire [31:0] a_read_output_1;
+ wire [31:0] b_read_output_1;
+ block_memory_16kbit #(
+ .initial_file("software/ram_1_byte0.hex")
+ ) ram_1_byte0(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_1[0]),
+ .port_a_write_input(a_write_input[7:0]),
+ .port_a_read_output(a_read_output_1[7:0]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_1[7:0])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_1_byte1.hex")
+ ) ram_1_byte1(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_1[1]),
+ .port_a_write_input(a_write_input[15:8]),
+ .port_a_read_output(a_read_output_1[15:8]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_1[15:8])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_1_byte2.hex")
+ ) ram_1_byte2(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_1[2]),
+ .port_a_write_input(a_write_input[23:16]),
+ .port_a_read_output(a_read_output_1[23:16]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_1[23:16])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_1_byte3.hex")
+ ) ram_1_byte3(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_1[3]),
+ .port_a_write_input(a_write_input[31:24]),
+ .port_a_read_output(a_read_output_1[31:24]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_1[31:24])
+ );
+
+
+ wire a_enable_2 = a_ram_address[31:11] == 2;
+ wire b_enable_2 = b_ram_address[31:11] == 2;
+ wire [3:0] a_write_enable_2 = {4{a_enable_2}} & a_write_enable;
+ wire [31:0] a_read_output_2;
+ wire [31:0] b_read_output_2;
+ block_memory_16kbit #(
+ .initial_file("software/ram_2_byte0.hex")
+ ) ram_2_byte0(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_2[0]),
+ .port_a_write_input(a_write_input[7:0]),
+ .port_a_read_output(a_read_output_2[7:0]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_2[7:0])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_2_byte1.hex")
+ ) ram_2_byte1(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_2[1]),
+ .port_a_write_input(a_write_input[15:8]),
+ .port_a_read_output(a_read_output_2[15:8]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_2[15:8])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_2_byte2.hex")
+ ) ram_2_byte2(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_2[2]),
+ .port_a_write_input(a_write_input[23:16]),
+ .port_a_read_output(a_read_output_2[23:16]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_2[23:16])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_2_byte3.hex")
+ ) ram_2_byte3(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_2[3]),
+ .port_a_write_input(a_write_input[31:24]),
+ .port_a_read_output(a_read_output_2[31:24]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_2[31:24])
+ );
+
+
+ wire a_enable_3 = a_ram_address[31:11] == 3;
+ wire b_enable_3 = b_ram_address[31:11] == 3;
+ wire [3:0] a_write_enable_3 = {4{a_enable_3}} & a_write_enable;
+ wire [31:0] a_read_output_3;
+ wire [31:0] b_read_output_3;
+ block_memory_16kbit #(
+ .initial_file("software/ram_3_byte0.hex")
+ ) ram_3_byte0(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_3[0]),
+ .port_a_write_input(a_write_input[7:0]),
+ .port_a_read_output(a_read_output_3[7:0]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_3[7:0])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_3_byte1.hex")
+ ) ram_3_byte1(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_3[1]),
+ .port_a_write_input(a_write_input[15:8]),
+ .port_a_read_output(a_read_output_3[15:8]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_3[15:8])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_3_byte2.hex")
+ ) ram_3_byte2(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_3[2]),
+ .port_a_write_input(a_write_input[23:16]),
+ .port_a_read_output(a_read_output_3[23:16]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_3[23:16])
+ );
+
+ block_memory_16kbit #(
+ .initial_file("software/ram_3_byte3.hex")
+ ) ram_3_byte3(
+ .clk(clk),
+ .port_a_address(a_ram_address[10:0]),
+ .port_a_write_enable(a_write_enable_3[3]),
+ .port_a_write_input(a_write_input[31:24]),
+ .port_a_read_output(a_read_output_3[31:24]),
+ .port_b_address(b_ram_address[10:0]),
+ .port_b_read_output(b_read_output_3[31:24])
+ );
+
+
+ always @* begin
+ case(a_ram_address[31:11])
+ 0: a_read_output = a_read_output_0;
+ 1: a_read_output = a_read_output_1;
+ 2: a_read_output = a_read_output_2;
+ 3: a_read_output = a_read_output_3;
+ default: a_read_output = 32'hXXXXXXXX;
+ endcase
+ end
+
+ always @* begin
+ case(b_ram_address[31:11])
+ 0: b_read_output = b_read_output_0;
+ 1: b_read_output = b_read_output_1;
+ 2: b_read_output = b_read_output_2;
+ 3: b_read_output = b_read_output_3;
+ default: b_read_output = 32'hXXXXXXXX;
+ endcase
+ end
+endmodule
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 1ps
+module block_memory_16kbit(
+ input clk,
+ input [10:0] port_a_address,
+ input port_a_write_enable,
+ input [7:0] port_a_write_input,
+ output [7:0] port_a_read_output,
+ input [10:0] port_b_address,
+ output [7:0] port_b_read_output
+ );
+
+ parameter initial_file = "";
+
+ (* ram_style = "block" *)
+ reg [7:0] ram[{11{1'b1}} : 0];
+
+ initial $readmemh(initial_file, ram);
+
+ reg [7:0] port_a_read_output_reg;
+ reg [7:0] port_b_read_output_reg;
+
+ always @(posedge clk) begin
+ port_b_read_output_reg <= ram[port_b_address];
+ if(port_a_write_enable) begin
+ ram[port_a_address] <= port_a_write_input;
+ end
+ else begin
+ port_a_read_output_reg <= ram[port_a_address];
+ end
+ end
+
+ assign port_a_read_output = port_a_read_output_reg;
+ assign port_b_read_output = port_b_read_output_reg;
+
+endmodule
--- /dev/null
+ADDRESS_SPACE ram COMBINED [0x10000:0x17FFF]
+ ADDRESS_RANGE RAMB16
+ BUS_BLOCK
+ cpu1/memory_interface/ram/ram_0_byte0/Mram_ram [7:0] LOC = X0Y30;
+ cpu1/memory_interface/ram/ram_0_byte1/Mram_ram [15:8] LOC = X0Y22;
+ cpu1/memory_interface/ram/ram_0_byte2/Mram_ram [23:16] LOC = X1Y30;
+ cpu1/memory_interface/ram/ram_0_byte3/Mram_ram [31:24] LOC = X1Y22;
+ END_BUS_BLOCK;
+ END_ADDRESS_RANGE;
+ ADDRESS_RANGE RAMB16
+ BUS_BLOCK
+ cpu1/memory_interface/ram/ram_1_byte0/Mram_ram [7:0] LOC = X0Y28;
+ cpu1/memory_interface/ram/ram_1_byte1/Mram_ram [15:8] LOC = X0Y20;
+ cpu1/memory_interface/ram/ram_1_byte2/Mram_ram [23:16] LOC = X1Y28;
+ cpu1/memory_interface/ram/ram_1_byte3/Mram_ram [31:24] LOC = X1Y20;
+ END_BUS_BLOCK;
+ END_ADDRESS_RANGE;
+ ADDRESS_RANGE RAMB16
+ BUS_BLOCK
+ cpu1/memory_interface/ram/ram_2_byte0/Mram_ram [7:0] LOC = X0Y26;
+ cpu1/memory_interface/ram/ram_2_byte1/Mram_ram [15:8] LOC = X0Y18;
+ cpu1/memory_interface/ram/ram_2_byte2/Mram_ram [23:16] LOC = X1Y26;
+ cpu1/memory_interface/ram/ram_2_byte3/Mram_ram [31:24] LOC = X1Y18;
+ END_BUS_BLOCK;
+ END_ADDRESS_RANGE;
+ ADDRESS_RANGE RAMB16
+ BUS_BLOCK
+ cpu1/memory_interface/ram/ram_3_byte0/Mram_ram [7:0] LOC = X0Y24;
+ cpu1/memory_interface/ram/ram_3_byte1/Mram_ram [15:8] LOC = X0Y16;
+ cpu1/memory_interface/ram/ram_3_byte2/Mram_ram [23:16] LOC = X1Y24;
+ cpu1/memory_interface/ram/ram_3_byte3/Mram_ram [31:24] LOC = X1Y16;
+ END_BUS_BLOCK;
+ END_ADDRESS_RANGE;
+END_ADDRESS_SPACE;
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 1ps
+`include "riscv.vh"
+`include "cpu.vh"
+
+module cpu(
+ input clk,
+ input reset,
+ output tty_write,
+ output [7:0] tty_write_data,
+ input tty_write_busy,
+ input switch_2,
+ input switch_3,
+ output led_1,
+ output led_3
+ );
+
+ parameter ram_size = 'h8000;
+ parameter ram_start = 32'h1_0000;
+ parameter reset_vector = ram_start;
+ parameter mtvec = ram_start + 'h40;
+
+ reg [31:0] registers[31:1];
+
+ wire [31:2] memory_interface_fetch_address;
+ wire [31:0] memory_interface_fetch_data;
+ wire memory_interface_fetch_valid;
+ wire [31:2] memory_interface_rw_address;
+ wire [3:0] memory_interface_rw_byte_mask;
+ wire memory_interface_rw_read_not_write;
+ wire memory_interface_rw_active;
+ wire [31:0] memory_interface_rw_data_in;
+ wire [31:0] memory_interface_rw_data_out;
+ wire memory_interface_rw_address_valid;
+ wire memory_interface_rw_wait;
+
+ cpu_memory_interface #(
+ .ram_size(ram_size),
+ .ram_start(ram_start)
+ ) memory_interface(
+ .clk(clk),
+ .reset(reset),
+ .fetch_address(memory_interface_fetch_address),
+ .fetch_data(memory_interface_fetch_data),
+ .fetch_valid(memory_interface_fetch_valid),
+ .rw_address(memory_interface_rw_address),
+ .rw_byte_mask(memory_interface_rw_byte_mask),
+ .rw_read_not_write(memory_interface_rw_read_not_write),
+ .rw_active(memory_interface_rw_active),
+ .rw_data_in(memory_interface_rw_data_in),
+ .rw_data_out(memory_interface_rw_data_out),
+ .rw_address_valid(memory_interface_rw_address_valid),
+ .rw_wait(memory_interface_rw_wait),
+ .tty_write(tty_write),
+ .tty_write_data(tty_write_data),
+ .tty_write_busy(tty_write_busy),
+ .switch_2(switch_2),
+ .switch_3(switch_3),
+ .led_1(led_1),
+ .led_3(led_3)
+ );
+
+ wire `fetch_action fetch_action;
+ wire [31:0] fetch_target_pc;
+ wire [31:0] fetch_output_pc;
+ wire [31:0] fetch_output_instruction;
+ wire `fetch_output_state fetch_output_state;
+
+ cpu_fetch_stage #(
+ .reset_vector(reset_vector),
+ .mtvec(mtvec)
+ ) fetch_stage(
+ .clk(clk),
+ .reset(reset),
+ .memory_interface_fetch_address(memory_interface_fetch_address),
+ .memory_interface_fetch_data(memory_interface_fetch_data),
+ .memory_interface_fetch_valid(memory_interface_fetch_valid),
+ .fetch_action(fetch_action),
+ .target_pc(fetch_target_pc),
+ .output_pc(fetch_output_pc),
+ .output_instruction(fetch_output_instruction),
+ .output_state(fetch_output_state)
+ );
+
+ wire [6:0] decoder_funct7;
+ wire [2:0] decoder_funct3;
+ wire [4:0] decoder_rd;
+ wire [4:0] decoder_rs1;
+ wire [4:0] decoder_rs2;
+ wire [31:0] decoder_immediate;
+ wire [6:0] decoder_opcode;
+ wire `decode_action decode_action;
+
+ cpu_decoder decoder(
+ .instruction(fetch_output_instruction),
+ .funct7(decoder_funct7),
+ .funct3(decoder_funct3),
+ .rd(decoder_rd),
+ .rs1(decoder_rs1),
+ .rs2(decoder_rs2),
+ .immediate(decoder_immediate),
+ .opcode(decoder_opcode),
+ .decode_action(decode_action));
+
+ wire [31:0] register_rs1 = (decoder_rs1 == 0) ? 0 : registers[decoder_rs1];
+ wire [31:0] register_rs2 = (decoder_rs2 == 0) ? 0 : registers[decoder_rs2];
+
+ wire [31:0] load_store_address = decoder_immediate + register_rs1;
+
+ wire [1:0] load_store_address_low_2 = decoder_immediate[1:0] + register_rs1[1:0];
+
+ function get_load_store_misaligned(
+ input [2:0] funct3,
+ input [1:0] load_store_address_low_2
+ );
+ begin
+ case(funct3[1:0])
+ `funct3_sb:
+ get_load_store_misaligned = 0;
+ `funct3_sh:
+ get_load_store_misaligned = load_store_address_low_2[0] != 0;
+ `funct3_sw:
+ get_load_store_misaligned = load_store_address_low_2[1:0] != 0;
+ default:
+ get_load_store_misaligned = 1'bX;
+ endcase
+ end
+ endfunction
+
+ wire load_store_misaligned = get_load_store_misaligned(decoder_funct3, load_store_address_low_2);
+
+ assign memory_interface_rw_address = load_store_address[31:2];
+
+ wire [3:0] unshifted_load_store_byte_mask = {decoder_funct3[1] ? 2'b11 : 2'b00, (decoder_funct3[1] | decoder_funct3[0]) ? 1'b1 : 1'b0, 1'b1};
+
+ assign memory_interface_rw_byte_mask = unshifted_load_store_byte_mask << load_store_address_low_2;
+
+ assign memory_interface_rw_data_in[31:24] = load_store_address_low_2[1]
+ ? (load_store_address_low_2[0] ? register_rs2[7:0] : register_rs2[15:8])
+ : (load_store_address_low_2[0] ? register_rs2[23:16] : register_rs2[31:24]);
+ assign memory_interface_rw_data_in[23:16] = load_store_address_low_2[1] ? register_rs2[7:0] : register_rs2[23:16];
+ assign memory_interface_rw_data_in[15:8] = load_store_address_low_2[0] ? register_rs2[7:0] : register_rs2[15:8];
+ assign memory_interface_rw_data_in[7:0] = register_rs2[7:0];
+
+ wire [31:0] unmasked_loaded_value;
+
+ assign unmasked_loaded_value[7:0] = load_store_address_low_2[1]
+ ? (load_store_address_low_2[0] ? memory_interface_rw_data_out[31:24] : memory_interface_rw_data_out[23:16])
+ : (load_store_address_low_2[0] ? memory_interface_rw_data_out[15:8] : memory_interface_rw_data_out[7:0]);
+ assign unmasked_loaded_value[15:8] = load_store_address_low_2[1] ? memory_interface_rw_data_out[31:24] : memory_interface_rw_data_out[15:8];
+ assign unmasked_loaded_value[31:16] = memory_interface_rw_data_out[31:16];
+
+ wire [31:0] loaded_value;
+
+ assign loaded_value[7:0] = unmasked_loaded_value[7:0];
+ assign loaded_value[15:8] = decoder_funct3[1:0] == 0 ? ({8{~decoder_funct3[2] & unmasked_loaded_value[7]}}) : unmasked_loaded_value[15:8];
+ assign loaded_value[31:16] = decoder_funct3[1] == 0 ? ({16{~decoder_funct3[2] & (decoder_funct3[0] ? unmasked_loaded_value[15] : unmasked_loaded_value[7])}}) : unmasked_loaded_value[31:16];
+
+ assign memory_interface_rw_active = ~reset
+ & (fetch_output_state == `fetch_output_state_valid)
+ & ~load_store_misaligned
+ & ((decode_action & (`decode_action_load | `decode_action_store)) != 0);
+
+ assign memory_interface_rw_read_not_write = ~decoder_opcode[5];
+
+ wire [31:0] alu_a = register_rs1;
+ wire [31:0] alu_b = decoder_opcode[5] ? register_rs2 : decoder_immediate;
+ wire [31:0] alu_result;
+
+ cpu_alu alu(
+ .funct7(decoder_funct7),
+ .funct3(decoder_funct3),
+ .opcode(decoder_opcode),
+ .a(alu_a),
+ .b(alu_b),
+ .result(alu_result)
+ );
+
+ wire [31:0] lui_auipc_result = decoder_opcode[5] ? decoder_immediate : decoder_immediate + fetch_output_pc;
+
+ assign fetch_target_pc[31:1] = ((decoder_opcode != `opcode_jalr ? fetch_output_pc[31:1] : register_rs1[31:1]) + decoder_immediate[31:1]);
+ assign fetch_target_pc[0] = 0;
+
+ wire misaligned_jump_target = fetch_target_pc[1];
+
+ wire [31:0] branch_arg_a = {register_rs1[31] ^ ~decoder_funct3[1], register_rs1[30:0]};
+ wire [31:0] branch_arg_b = {register_rs2[31] ^ ~decoder_funct3[1], register_rs2[30:0]};
+
+ wire branch_taken = decoder_funct3[0] ^ (decoder_funct3[2] ? branch_arg_a < branch_arg_b : branch_arg_a == branch_arg_b);
+
+ reg [31:0] mcause = 0;
+ reg [31:0] mepc = 32'hXXXXXXXX;
+ reg [31:0] mscratch = 32'hXXXXXXXX;
+
+ reg mstatus_mpie = 1'bX;
+ reg mstatus_mie = 0;
+ parameter mstatus_mprv = 0;
+ parameter mstatus_tsr = 0;
+ parameter mstatus_tw = 0;
+ parameter mstatus_tvm = 0;
+ parameter mstatus_mxr = 0;
+ parameter mstatus_sum = 0;
+ parameter mstatus_xs = 0;
+ parameter mstatus_fs = 0;
+ parameter mstatus_mpp = 2'b11;
+ parameter mstatus_spp = 0;
+ parameter mstatus_spie = 0;
+ parameter mstatus_upie = 0;
+ parameter mstatus_sie = 0;
+ parameter mstatus_uie = 0;
+
+ reg mie_meie = 1'bX;
+ reg mie_mtie = 1'bX;
+ reg mie_msie = 1'bX;
+ parameter mie_seie = 0;
+ parameter mie_ueie = 0;
+ parameter mie_stie = 0;
+ parameter mie_utie = 0;
+ parameter mie_ssie = 0;
+ parameter mie_usie = 0;
+
+ task reset_to_initial;
+ begin
+ mcause = 0;
+ mepc = 32'hXXXXXXXX;
+ mscratch = 32'hXXXXXXXX;
+ mstatus_mie = 0;
+ mstatus_mpie = 1'bX;
+ mie_meie = 1'bX;
+ mie_mtie = 1'bX;
+ mie_msie = 1'bX;
+ registers['h01] <= 32'hXXXXXXXX;
+ registers['h02] <= 32'hXXXXXXXX;
+ registers['h03] <= 32'hXXXXXXXX;
+ registers['h04] <= 32'hXXXXXXXX;
+ registers['h05] <= 32'hXXXXXXXX;
+ registers['h06] <= 32'hXXXXXXXX;
+ registers['h07] <= 32'hXXXXXXXX;
+ registers['h08] <= 32'hXXXXXXXX;
+ registers['h09] <= 32'hXXXXXXXX;
+ registers['h0A] <= 32'hXXXXXXXX;
+ registers['h0B] <= 32'hXXXXXXXX;
+ registers['h0C] <= 32'hXXXXXXXX;
+ registers['h0D] <= 32'hXXXXXXXX;
+ registers['h0E] <= 32'hXXXXXXXX;
+ registers['h0F] <= 32'hXXXXXXXX;
+ registers['h10] <= 32'hXXXXXXXX;
+ registers['h11] <= 32'hXXXXXXXX;
+ registers['h12] <= 32'hXXXXXXXX;
+ registers['h13] <= 32'hXXXXXXXX;
+ registers['h14] <= 32'hXXXXXXXX;
+ registers['h15] <= 32'hXXXXXXXX;
+ registers['h16] <= 32'hXXXXXXXX;
+ registers['h17] <= 32'hXXXXXXXX;
+ registers['h18] <= 32'hXXXXXXXX;
+ registers['h19] <= 32'hXXXXXXXX;
+ registers['h1A] <= 32'hXXXXXXXX;
+ registers['h1B] <= 32'hXXXXXXXX;
+ registers['h1C] <= 32'hXXXXXXXX;
+ registers['h1D] <= 32'hXXXXXXXX;
+ registers['h1E] <= 32'hXXXXXXXX;
+ registers['h1F] <= 32'hXXXXXXXX;
+ end
+ endtask
+
+ task write_register(input [4:0] register_number, input [31:0] value);
+ begin
+ if(register_number != 0)
+ registers[register_number] <= value;
+ end
+ endtask
+
+ function [31:0] evaluate_csr_funct3_operation(input [2:0] funct3, input [31:0] previous_value, input [31:0] written_value);
+ begin
+ case(funct3)
+ `funct3_csrrw, `funct3_csrrwi:
+ evaluate_csr_funct3_operation = written_value;
+ `funct3_csrrs, `funct3_csrrsi:
+ evaluate_csr_funct3_operation = written_value | previous_value;
+ `funct3_csrrc, `funct3_csrrci:
+ evaluate_csr_funct3_operation = ~written_value & previous_value;
+ default:
+ evaluate_csr_funct3_operation = 32'hXXXXXXXX;
+ endcase
+ end
+ endfunction
+
+ parameter misa_a = 1'b0;
+ parameter misa_b = 1'b0;
+ parameter misa_c = 1'b0;
+ parameter misa_d = 1'b0;
+ parameter misa_e = 1'b0;
+ parameter misa_f = 1'b0;
+ parameter misa_g = 1'b0;
+ parameter misa_h = 1'b0;
+ parameter misa_i = 1'b1;
+ parameter misa_j = 1'b0;
+ parameter misa_k = 1'b0;
+ parameter misa_l = 1'b0;
+ parameter misa_m = 1'b0;
+ parameter misa_n = 1'b0;
+ parameter misa_o = 1'b0;
+ parameter misa_p = 1'b0;
+ parameter misa_q = 1'b0;
+ parameter misa_r = 1'b0;
+ parameter misa_s = 1'b0;
+ parameter misa_t = 1'b0;
+ parameter misa_u = 1'b0;
+ parameter misa_v = 1'b0;
+ parameter misa_w = 1'b0;
+ parameter misa_x = 1'b0;
+ parameter misa_y = 1'b0;
+ parameter misa_z = 1'b0;
+ parameter misa = {
+ 2'b01,
+ 4'b0,
+ misa_z,
+ misa_y,
+ misa_x,
+ misa_w,
+ misa_v,
+ misa_u,
+ misa_t,
+ misa_s,
+ misa_r,
+ misa_q,
+ misa_p,
+ misa_o,
+ misa_n,
+ misa_m,
+ misa_l,
+ misa_k,
+ misa_j,
+ misa_i,
+ misa_h,
+ misa_g,
+ misa_f,
+ misa_e,
+ misa_d,
+ misa_c,
+ misa_b,
+ misa_a};
+
+ parameter mvendorid = 32'b0;
+ parameter marchid = 32'b0;
+ parameter mimpid = 32'b0;
+ parameter mhartid = 32'b0;
+
+ function [31:0] make_mstatus(input mstatus_tsr,
+ input mstatus_tw,
+ input mstatus_tvm,
+ input mstatus_mxr,
+ input mstatus_sum,
+ input mstatus_mprv,
+ input [1:0] mstatus_xs,
+ input [1:0] mstatus_fs,
+ input [1:0] mstatus_mpp,
+ input mstatus_spp,
+ input mstatus_mpie,
+ input mstatus_spie,
+ input mstatus_upie,
+ input mstatus_mie,
+ input mstatus_sie,
+ input mstatus_uie);
+ begin
+ make_mstatus = {(mstatus_xs == 2'b11) | (mstatus_fs == 2'b11),
+ 8'b0,
+ mstatus_tsr,
+ mstatus_tw,
+ mstatus_tvm,
+ mstatus_mxr,
+ mstatus_sum,
+ mstatus_mprv,
+ mstatus_xs,
+ mstatus_fs,
+ mstatus_mpp,
+ 2'b0,
+ mstatus_spp,
+ mstatus_mpie,
+ 1'b0,
+ mstatus_spie,
+ mstatus_upie,
+ mstatus_mie,
+ 1'b0,
+ mstatus_sie,
+ mstatus_uie};
+ end
+ endfunction
+
+ wire mip_meip = 0; // TODO: implement external interrupts
+ parameter mip_seip = 0;
+ parameter mip_ueip = 0;
+ wire mip_mtip = 0; // TODO: implement timer interrupts
+ parameter mip_stip = 0;
+ parameter mip_utip = 0;
+ parameter mip_msip = 0;
+ parameter mip_ssip = 0;
+ parameter mip_usip = 0;
+
+ wire csr_op_is_valid;
+
+ function `fetch_action get_fetch_action(
+ input `fetch_output_state fetch_output_state,
+ input `decode_action decode_action,
+ input load_store_misaligned,
+ input memory_interface_rw_address_valid,
+ input memory_interface_rw_wait,
+ input branch_taken,
+ input misaligned_jump_target,
+ input csr_op_is_valid
+ );
+ begin
+ case(fetch_output_state)
+ `fetch_output_state_empty:
+ get_fetch_action = `fetch_action_default;
+ `fetch_output_state_trap:
+ get_fetch_action = `fetch_action_ack_trap;
+ `fetch_output_state_valid: begin
+ if((decode_action & `decode_action_trap_illegal_instruction) != 0) begin
+ get_fetch_action = `fetch_action_error_trap;
+ end
+ else if((decode_action & `decode_action_trap_ecall_ebreak) != 0) begin
+ get_fetch_action = `fetch_action_noerror_trap;
+ end
+ else if((decode_action & (`decode_action_load | `decode_action_store)) != 0) begin
+ if(load_store_misaligned | ~memory_interface_rw_address_valid) begin
+ get_fetch_action = `fetch_action_error_trap;
+ end
+ else if(memory_interface_rw_wait) begin
+ get_fetch_action = `fetch_action_wait;
+ end
+ else begin
+ get_fetch_action = `fetch_action_default;
+ end
+ end
+ else if((decode_action & `decode_action_fence_i) != 0) begin
+ get_fetch_action = `fetch_action_fence;
+ end
+ else if((decode_action & `decode_action_branch) != 0) begin
+ if(branch_taken) begin
+ if(misaligned_jump_target) begin
+ get_fetch_action = `fetch_action_error_trap;
+ end
+ else begin
+ get_fetch_action = `fetch_action_jump;
+ end
+ end
+ else
+ begin
+ get_fetch_action = `fetch_action_default;
+ end
+ end
+ else if((decode_action & (`decode_action_jal | `decode_action_jalr)) != 0) begin
+ if(misaligned_jump_target) begin
+ get_fetch_action = `fetch_action_error_trap;
+ end
+ else begin
+ get_fetch_action = `fetch_action_jump;
+ end
+ end
+ else if((decode_action & `decode_action_csr) != 0) begin
+ if(csr_op_is_valid)
+ get_fetch_action = `fetch_action_default;
+ else
+ get_fetch_action = `fetch_action_error_trap;
+ end
+ else begin
+ get_fetch_action = `fetch_action_default;
+ end
+ end
+ default:
+ get_fetch_action = 32'hXXXXXXXX;
+ endcase
+ end
+ endfunction
+
+ assign fetch_action = get_fetch_action(
+ fetch_output_state,
+ decode_action,
+ load_store_misaligned,
+ memory_interface_rw_address_valid,
+ memory_interface_rw_wait,
+ branch_taken,
+ misaligned_jump_target,
+ csr_op_is_valid
+ );
+
+ task handle_trap;
+ begin
+ mstatus_mpie = mstatus_mie;
+ mstatus_mie = 0;
+ mepc = (fetch_action == `fetch_action_noerror_trap) ? fetch_output_pc + 4 : fetch_output_pc;
+ if(fetch_action == `fetch_action_ack_trap) begin
+ mcause = `cause_instruction_access_fault;
+ end
+ else if((decode_action & `decode_action_trap_illegal_instruction) != 0) begin
+ mcause = `cause_illegal_instruction;
+ end
+ else if((decode_action & `decode_action_trap_ecall_ebreak) != 0) begin
+ mcause = decoder_immediate[0] ? `cause_machine_environment_call : `cause_breakpoint;
+ end
+ else if((decode_action & `decode_action_load) != 0) begin
+ if(load_store_misaligned)
+ mcause = `cause_load_address_misaligned;
+ else
+ mcause = `cause_load_access_fault;
+ end
+ else if((decode_action & `decode_action_store) != 0) begin
+ if(load_store_misaligned)
+ mcause = `cause_store_amo_address_misaligned;
+ else
+ mcause = `cause_store_amo_access_fault;
+ end
+ else if((decode_action & (`decode_action_branch | `decode_action_jal | `decode_action_jalr)) != 0) begin
+ mcause = `cause_instruction_address_misaligned;
+ end
+ else begin
+ mcause = `cause_illegal_instruction;
+ end
+ end
+ endtask
+
+ wire [11:0] csr_number = decoder_immediate;
+ wire [31:0] csr_input_value = decoder_funct3[2] ? decoder_rs1 : register_rs1;
+ wire csr_reads = decoder_funct3[1] | (decoder_rd != 0);
+ wire csr_writes = ~decoder_funct3[1] | (decoder_rs1 != 0);
+
+ function get_csr_op_is_valid(input [11:0] csr_number, input csr_reads, input csr_writes);
+ begin
+ case(csr_number)
+ `csr_ustatus,
+ `csr_fflags,
+ `csr_frm,
+ `csr_fcsr,
+ `csr_uie,
+ `csr_utvec,
+ `csr_uscratch,
+ `csr_uepc,
+ `csr_ucause,
+ `csr_utval,
+ `csr_uip,
+ `csr_sstatus,
+ `csr_sedeleg,
+ `csr_sideleg,
+ `csr_sie,
+ `csr_stvec,
+ `csr_scounteren,
+ `csr_sscratch,
+ `csr_sepc,
+ `csr_scause,
+ `csr_stval,
+ `csr_sip,
+ `csr_satp,
+ `csr_medeleg,
+ `csr_mideleg,
+ `csr_dcsr,
+ `csr_dpc,
+ `csr_dscratch:
+ get_csr_op_is_valid = 0;
+ `csr_cycle,
+ `csr_time,
+ `csr_instret,
+ `csr_cycleh,
+ `csr_timeh,
+ `csr_instreth,
+ `csr_mvendorid,
+ `csr_marchid,
+ `csr_mimpid,
+ `csr_mhartid:
+ get_csr_op_is_valid = ~csr_writes;
+ `csr_misa,
+ `csr_mstatus,
+ `csr_mie,
+ `csr_mtvec,
+ `csr_mscratch,
+ `csr_mepc,
+ `csr_mcause,
+ `csr_mip:
+ get_csr_op_is_valid = 1;
+ `csr_mcounteren,
+ `csr_mtval,
+ `csr_mcycle,
+ `csr_minstret,
+ `csr_mcycleh,
+ `csr_minstreth:
+ // TODO: CSRs not implemented yet
+ get_csr_op_is_valid = 0;
+ endcase
+ end
+ endfunction
+
+ assign csr_op_is_valid = get_csr_op_is_valid(csr_number, csr_reads, csr_writes);
+
+ wire [63:0] cycle_counter = 0; // TODO: implement cycle_counter
+ wire [63:0] time_counter = 0; // TODO: implement time_counter
+ wire [63:0] instret_counter = 0; // TODO: implement instret_counter
+
+ always @(posedge clk) begin:main_block
+ if(reset) begin
+ reset_to_initial();
+ disable main_block;
+ end
+ case(fetch_output_state)
+ `fetch_output_state_empty: begin
+ end
+ `fetch_output_state_trap: begin
+ handle_trap();
+ end
+ `fetch_output_state_valid: begin:valid
+ if((fetch_action == `fetch_action_error_trap) | (fetch_action == `fetch_action_noerror_trap)) begin
+ handle_trap();
+ end
+ else if((decode_action & `decode_action_load) != 0) begin
+ if(~memory_interface_rw_wait)
+ write_register(decoder_rd, loaded_value);
+ end
+ else if((decode_action & `decode_action_op_op_imm) != 0) begin
+ write_register(decoder_rd, alu_result);
+ end
+ else if((decode_action & `decode_action_lui_auipc) != 0) begin
+ write_register(decoder_rd, lui_auipc_result);
+ end
+ else if((decode_action & (`decode_action_jal | `decode_action_jalr)) != 0) begin
+ write_register(decoder_rd, fetch_output_pc + 4);
+ end
+ else if((decode_action & `decode_action_csr) != 0) begin:csr
+ reg [31:0] csr_output_value;
+ reg [31:0] csr_written_value;
+ csr_output_value = 32'hXXXXXXXX;
+ csr_written_value = 32'hXXXXXXXX;
+ case(csr_number)
+ `csr_cycle: begin
+ csr_output_value = cycle_counter[31:0];
+ end
+ `csr_time: begin
+ csr_output_value = time_counter[31:0];
+ end
+ `csr_instret: begin
+ csr_output_value = instret_counter[31:0];
+ end
+ `csr_cycleh: begin
+ csr_output_value = cycle_counter[63:32];
+ end
+ `csr_timeh: begin
+ csr_output_value = time_counter[63:32];
+ end
+ `csr_instreth: begin
+ csr_output_value = instret_counter[63:32];
+ end
+ `csr_mvendorid: begin
+ csr_output_value = mvendorid;
+ end
+ `csr_marchid: begin
+ csr_output_value = marchid;
+ end
+ `csr_mimpid: begin
+ csr_output_value = mimpid;
+ end
+ `csr_mhartid: begin
+ csr_output_value = mhartid;
+ end
+ `csr_misa: begin
+ csr_output_value = misa;
+ end
+ `csr_mstatus: begin
+ csr_output_value = make_mstatus(mstatus_tsr,
+ mstatus_tw,
+ mstatus_tvm,
+ mstatus_mxr,
+ mstatus_sum,
+ mstatus_mprv,
+ mstatus_xs,
+ mstatus_fs,
+ mstatus_mpp,
+ mstatus_spp,
+ mstatus_mpie,
+ mstatus_spie,
+ mstatus_upie,
+ mstatus_mie,
+ mstatus_sie,
+ mstatus_uie);
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes) begin
+ mstatus_mpie = csr_written_value[7];
+ mstatus_mie = csr_written_value[3];
+ end
+ end
+ `csr_mie: begin
+ csr_output_value = 0;
+ csr_output_value[11] = mie_meie;
+ csr_output_value[9] = mie_seie;
+ csr_output_value[8] = mie_ueie;
+ csr_output_value[7] = mie_mtie;
+ csr_output_value[5] = mie_stie;
+ csr_output_value[4] = mie_utie;
+ csr_output_value[3] = mie_msie;
+ csr_output_value[1] = mie_ssie;
+ csr_output_value[0] = mie_usie;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes) begin
+ mie_meie = csr_written_value[11];
+ mie_mtie = csr_written_value[7];
+ mie_msie = csr_written_value[3];
+ end
+ end
+ `csr_mtvec: begin
+ csr_output_value = mtvec;
+ end
+ `csr_mscratch: begin
+ csr_output_value = mscratch;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes)
+ mscratch = csr_written_value;
+ end
+ `csr_mepc: begin
+ csr_output_value = mepc;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes)
+ mepc = csr_written_value;
+ end
+ `csr_mcause: begin
+ csr_output_value = mcause;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes)
+ mcause = csr_written_value;
+ end
+ `csr_mip: begin
+ csr_output_value = 0;
+ csr_output_value[11] = mip_meip;
+ csr_output_value[9] = mip_seip;
+ csr_output_value[8] = mip_ueip;
+ csr_output_value[7] = mip_mtip;
+ csr_output_value[5] = mip_stip;
+ csr_output_value[4] = mip_utip;
+ csr_output_value[3] = mip_msip;
+ csr_output_value[1] = mip_ssip;
+ csr_output_value[0] = mip_usip;
+ end
+ endcase
+ if(csr_reads)
+ write_register(decoder_rd, csr_output_value);
+ end
+ else if((decode_action & (`decode_action_fence | `decode_action_fence_i | `decode_action_store | `decode_action_branch)) != 0) begin
+ // do nothing
+ end
+ end
+ endcase
+ end
+
+endmodule
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`ifndef cpu_vh_
+`define cpu_vh_
+
+`define fetch_action [2:0]
+
+`define fetch_action_default 3'h0
+`define fetch_action_fence 3'h1
+`define fetch_action_jump 3'h2
+`define fetch_action_wait 3'h3
+`define fetch_action_error_trap 3'h4
+`define fetch_action_noerror_trap 3'h5
+`define fetch_action_ack_trap 3'h6
+
+`define fetch_output_state [1:0]
+
+`define fetch_output_state_empty 2'h0
+`define fetch_output_state_valid 2'h1
+`define fetch_output_state_trap 2'h2
+
+`define decode_action [11:0]
+
+`define decode_action_trap_illegal_instruction 'h1
+`define decode_action_load 'h2
+`define decode_action_fence 'h4
+`define decode_action_fence_i 'h8
+`define decode_action_op_op_imm 'h10
+`define decode_action_lui_auipc 'h20
+`define decode_action_store 'h40
+`define decode_action_branch 'h80
+`define decode_action_jalr 'h100
+`define decode_action_jal 'h200
+`define decode_action_trap_ecall_ebreak 'h400
+`define decode_action_csr 'h800
+
+`endif
+
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 1ps
+`include "riscv.vh"
+
+module cpu_alu(
+ input [6:0] funct7,
+ input [2:0] funct3,
+ input [6:0] opcode,
+ input [31:0] a,
+ input [31:0] b,
+ output [31:0] result
+ );
+
+ wire is_sub = funct7[5] & opcode[5];
+ wire [31:0] add_sub_result = a + (is_sub ? ~b : b) + is_sub;
+ wire [31:0] shift_left_result = a << b[4:0];
+ wire [31:0] shift_right_result = funct7[5] ? $unsigned($signed(a) >>> b[4:0]) : a >> b[4:0];
+ wire [31:0] xor_result = a ^ b;
+ wire [31:0] or_result = a | b;
+ wire [31:0] and_result = a & b;
+ wire [31:0] lt_arg_flip = {~funct3[0], 31'b0};
+ wire [31:0] lt_result = ((a ^ lt_arg_flip) < (b ^ lt_arg_flip)) ? 32'b1 : 32'b0;
+
+ function [31:0] mux8(
+ input [2:0] select,
+ input [31:0] v0,
+ input [31:0] v1,
+ input [31:0] v2,
+ input [31:0] v3,
+ input [31:0] v4,
+ input [31:0] v5,
+ input [31:0] v6,
+ input [31:0] v7);
+ begin
+ case(select)
+ 0: mux8 = v0;
+ 1: mux8 = v1;
+ 2: mux8 = v2;
+ 3: mux8 = v3;
+ 4: mux8 = v4;
+ 5: mux8 = v5;
+ 6: mux8 = v6;
+ 7: mux8 = v7;
+ default: mux8 = 32'hXXXXXXXX;
+ endcase
+ end
+ endfunction
+
+ assign result = mux8(funct3,
+ add_sub_result,
+ shift_left_result,
+ lt_result,
+ lt_result,
+ xor_result,
+ shift_right_result,
+ or_result,
+ and_result);
+
+endmodule
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 100ps
+`include "riscv.vh"
+`include "cpu.vh"
+
+module cpu_decoder(
+ input [31:0] instruction,
+ output [6:0] funct7,
+ output [2:0] funct3,
+ output [4:0] rd,
+ output [4:0] rs1,
+ output [4:0] rs2,
+ output [31:0] immediate,
+ output [6:0] opcode,
+ output `decode_action decode_action
+ );
+
+ assign funct7 = instruction[31:25];
+ assign funct3 = instruction[14:12];
+ assign rd = instruction[11:7];
+ assign rs1 = instruction[19:15];
+ assign rs2 = instruction[24:20];
+ assign opcode = instruction[6:0];
+
+ function [31:0] calculate_immediate(input [31:0] instruction, input [6:0] opcode);
+ begin
+ case(opcode)
+ `opcode_amo,
+ `opcode_op,
+ `opcode_op_32,
+ `opcode_op_fp:
+ // R-type: no immediate
+ calculate_immediate = 32'hXXXXXXXX;
+ `opcode_load,
+ `opcode_load_fp,
+ `opcode_misc_mem,
+ `opcode_op_imm,
+ `opcode_op_imm_32,
+ `opcode_jalr,
+ `opcode_system:
+ // I-type
+ calculate_immediate = {{20{instruction[31]}}, instruction[31:20]};
+ `opcode_store,
+ `opcode_store_fp:
+ // S-type
+ calculate_immediate = {{21{instruction[31]}}, instruction[30:25], instruction[11:7]};
+ `opcode_branch:
+ // B-type
+ calculate_immediate = {{20{instruction[31]}}, instruction[7], instruction[30:25], instruction[11:8], 1'b0};
+ `opcode_auipc,
+ `opcode_lui:
+ // U-type
+ calculate_immediate = {instruction[31:12], 12'b0};
+ `opcode_jal:
+ // J-type
+ calculate_immediate = {{12{instruction[31]}}, instruction[19:12], instruction[20], instruction[30:25], instruction[24:21], 1'b0};
+ `opcode_madd,
+ `opcode_msub,
+ `opcode_nmsub,
+ `opcode_nmadd:
+ // R4-type: no immediate
+ calculate_immediate = 32'hXXXXXXXX;
+ `opcode_custom_0,
+ `opcode_48b_escape_0,
+ `opcode_custom_1,
+ `opcode_64b_escape,
+ `opcode_reserved_10101,
+ `opcode_rv128_0,
+ `opcode_48b_escape_1,
+ `opcode_reserved_11010,
+ `opcode_reserved_11101,
+ `opcode_rv128_1,
+ `opcode_80b_escape:
+ // unknown
+ calculate_immediate = 32'hXXXXXXXX;
+ default:
+ calculate_immediate = 32'hXXXXXXXX;
+ endcase
+ end
+ endfunction
+
+ assign immediate = calculate_immediate(instruction, opcode);
+
+ function `decode_action calculate_action(
+ input [6:0] funct7,
+ input [2:0] funct3,
+ input [4:0] rd,
+ input [4:0] rs1,
+ input [4:0] rs2,
+ input [31:0] immediate,
+ input [6:0] opcode);
+ begin
+ case(opcode)
+ `opcode_load: begin
+ case(funct3)
+ `funct3_lb,
+ `funct3_lbu,
+ `funct3_lh,
+ `funct3_lhu,
+ `funct3_lw:
+ calculate_action = `decode_action_load;
+ default:
+ calculate_action = `decode_action_trap_illegal_instruction;
+ endcase
+ end
+ `opcode_misc_mem: begin
+ if(funct3 == `funct3_fence) begin
+ if((immediate[11:8] == 0) & (rs1 == 0) & (rd == 0))
+ calculate_action = `decode_action_fence;
+ else
+ calculate_action = `decode_action_trap_illegal_instruction;
+ end
+ else if(funct3 == `funct3_fence_i) begin
+ if((immediate[11:0] == 0) & (rs1 == 0) & (rd == 0))
+ calculate_action = `decode_action_fence_i;
+ else
+ calculate_action = `decode_action_trap_illegal_instruction;
+ end
+ else
+ begin
+ calculate_action = `decode_action_trap_illegal_instruction;
+ end
+ end
+ `opcode_op_imm,
+ `opcode_op: begin
+ if(funct3 == `funct3_slli) begin
+ if(funct7 == 0)
+ calculate_action = `decode_action_op_op_imm;
+ else
+ calculate_action = `decode_action_trap_illegal_instruction;
+ end
+ else if(funct3 == `funct3_srli_srai) begin
+ if(funct7 == 0 || funct7 == 7'h20)
+ calculate_action = `decode_action_op_op_imm;
+ else
+ calculate_action = `decode_action_trap_illegal_instruction;
+ end
+ else begin
+ calculate_action = `decode_action_op_op_imm;
+ end
+ end
+ `opcode_lui,
+ `opcode_auipc: begin
+ calculate_action = `decode_action_lui_auipc;
+ end
+ `opcode_store: begin
+ case(funct3)
+ `funct3_sb,
+ `funct3_sh,
+ `funct3_sw:
+ calculate_action = `decode_action_store;
+ default:
+ calculate_action = `decode_action_trap_illegal_instruction;
+ endcase
+ end
+ `opcode_branch: begin
+ case(funct3)
+ `funct3_beq,
+ `funct3_bne,
+ `funct3_blt,
+ `funct3_bge,
+ `funct3_bltu,
+ `funct3_bgeu:
+ calculate_action = `decode_action_branch;
+ default:
+ calculate_action = `decode_action_trap_illegal_instruction;
+ endcase
+ end
+ `opcode_jalr: begin
+ if(funct3 == `funct3_jalr)
+ calculate_action = `decode_action_jalr;
+ else
+ calculate_action = `decode_action_trap_illegal_instruction;
+ end
+ `opcode_jal: begin
+ calculate_action = `decode_action_jal;
+ end
+ `opcode_system: begin
+ case(funct3)
+ `funct3_ecall_ebreak:
+ if((rs1 != 0) | (rd != 0) | ((immediate & ~32'b1) != 0))
+ calculate_action = `decode_action_trap_illegal_instruction;
+ else
+ calculate_action = `decode_action_trap_ecall_ebreak;
+ `funct3_csrrw,
+ `funct3_csrrs,
+ `funct3_csrrc,
+ `funct3_csrrwi,
+ `funct3_csrrsi,
+ `funct3_csrrci:
+ calculate_action = `decode_action_csr;
+ default:
+ calculate_action = `decode_action_trap_illegal_instruction;
+ endcase
+ end
+ `opcode_load_fp,
+ `opcode_custom_0,
+ `opcode_op_imm_32,
+ `opcode_48b_escape_0,
+ `opcode_store_fp,
+ `opcode_custom_1,
+ `opcode_amo,
+ `opcode_op_32,
+ `opcode_64b_escape,
+ `opcode_madd,
+ `opcode_msub,
+ `opcode_nmsub,
+ `opcode_nmadd,
+ `opcode_op_fp,
+ `opcode_reserved_10101,
+ `opcode_rv128_0,
+ `opcode_48b_escape_1,
+ `opcode_reserved_11010,
+ `opcode_reserved_11101,
+ `opcode_rv128_1,
+ `opcode_80b_escape: begin
+ calculate_action = `decode_action_trap_illegal_instruction;
+ end
+ default:
+ calculate_action = `decode_action_trap_illegal_instruction;
+ endcase
+ end
+ endfunction
+
+ assign decode_action = calculate_action(funct7,
+ funct3,
+ rd,
+ rs1,
+ rs2,
+ immediate,
+ opcode);
+
+endmodule
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 1ps
+`include "riscv.vh"
+`include "cpu.vh"
+
+module cpu_fetch_stage(
+ input clk,
+ input reset,
+ output [31:2] memory_interface_fetch_address,
+ input [31:0] memory_interface_fetch_data,
+ input memory_interface_fetch_valid,
+ input `fetch_action fetch_action,
+ input [31:0] target_pc,
+ output reg [31:0] output_pc,
+ output [31:0] output_instruction,
+ output reg `fetch_output_state output_state
+ );
+
+ parameter reset_vector = 32'hXXXXXXXX;
+ parameter mtvec = 32'hXXXXXXXX;
+
+ reg [31:0] fetch_pc = reset_vector;
+
+ always @(posedge clk or posedge reset) output_pc <= reset ? reset_vector : ((fetch_action == `fetch_action_wait) ? output_pc : fetch_pc);
+
+ assign memory_interface_fetch_address = fetch_pc[31:2];
+
+ initial output_pc <= reset_vector;
+ initial output_state <= `fetch_output_state_empty;
+
+ reg [31:0] delayed_instruction = 0;
+ reg delayed_instruction_valid = 0;
+
+ always @(posedge clk or posedge reset) delayed_instruction <= reset ? 0 : output_instruction;
+
+ assign output_instruction = delayed_instruction_valid ? delayed_instruction : memory_interface_fetch_data;
+
+ always @(posedge clk or posedge reset) begin
+ if(reset)
+ delayed_instruction_valid <= 0;
+ else
+ delayed_instruction_valid <= fetch_action == `fetch_action_wait;
+ end
+
+ always @(posedge clk or posedge reset) begin
+ if(reset) begin
+ fetch_pc <= reset_vector;
+ output_state <= `fetch_output_state_empty;
+ end
+ else begin
+ case(fetch_action)
+ `fetch_action_default,
+ `fetch_action_ack_trap: begin
+ if(memory_interface_fetch_valid) begin
+ fetch_pc <= fetch_pc + 4;
+ output_state <= `fetch_output_state_valid;
+ end
+ else begin
+ fetch_pc <= mtvec;
+ output_state <= `fetch_output_state_trap;
+ end
+ end
+ `fetch_action_fence: begin
+ fetch_pc <= output_pc + 4;
+ output_state <= `fetch_output_state_empty;
+ end
+ `fetch_action_jump: begin
+ fetch_pc <= target_pc;
+ output_state <= `fetch_output_state_empty;
+ end
+ `fetch_action_error_trap,
+ `fetch_action_noerror_trap: begin
+ fetch_pc <= mtvec;
+ output_state <= `fetch_output_state_empty;
+ end
+ `fetch_action_wait: begin
+ fetch_pc <= fetch_pc;
+ output_state <= `fetch_output_state_valid;
+ end
+ endcase
+ end
+ end
+endmodule
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 1ps
+module cpu_memory_interface(
+ input clk,
+ input reset,
+ input [31:2] fetch_address,
+ output [31:0] fetch_data,
+ output fetch_valid,
+ input [31:2] rw_address,
+ input [3:0] rw_byte_mask,
+ input rw_read_not_write,
+ input rw_active,
+ input [31:0] rw_data_in,
+ output [31:0] rw_data_out,
+ output rw_address_valid,
+ output rw_wait,
+ output reg tty_write,
+ output reg [7:0] tty_write_data,
+ input tty_write_busy,
+ input switch_2,
+ input switch_3,
+ output led_1,
+ output led_3
+ );
+
+ parameter ram_size = 32'hXXXXXXXX;
+ parameter ram_start = 32'hXXXXXXXX;
+ parameter tty_location = 32'h8000_0000;
+ parameter gpio_location = 32'h8000_0010;
+
+ wire ram_a_write_enable = ~reset & ~ignore_after_delay & rw_active & rw_address_in_mem_space & ~rw_read_not_write;
+
+ wire [31:0] ram_a_ram_address = rw_address_in_mem_space ? rw_address - ram_start / 4 : 0;
+ wire [3:0] ram_a_write_enable_bytes = {4{ram_a_write_enable}} & rw_byte_mask;
+ wire [31:0] ram_a_write_input = rw_data_in;
+ wire [31:0] ram_a_read_output;
+ wire [31:0] ram_b_ram_address = fetch_address_valid ? fetch_address - ram_start / 4 : 0;
+ wire [31:0] ram_b_read_output;
+
+ block_memory ram(
+ .clk(clk),
+ .a_ram_address(ram_a_ram_address),
+ .a_write_enable(ram_a_write_enable_bytes),
+ .a_write_input(ram_a_write_input),
+ .a_read_output(ram_a_read_output),
+ .b_ram_address(ram_b_ram_address),
+ .b_read_output(ram_b_read_output)
+ );
+
+ wire fetch_address_valid = (fetch_address >= ram_start / 4) & (fetch_address < (ram_start + ram_size) / 4);
+ wire rw_address_is_tty = (rw_address == tty_location / 4) & (rw_read_not_write | rw_byte_mask == 4'h1);
+ wire rw_address_is_gpio = rw_address == gpio_location / 4;
+ wire rw_address_in_io_space = rw_address_is_tty | rw_address_is_gpio;
+ wire rw_address_in_mem_space = (rw_address >= ram_start / 4) & (rw_address < (ram_start + ram_size) / 4);
+ assign rw_address_valid = rw_address_in_mem_space | rw_address_in_io_space;
+
+ reg delay_done = 0;
+
+ assign fetch_data = ram_b_read_output;
+
+ assign fetch_valid = ~reset & fetch_address_valid;
+
+ assign rw_wait = (rw_address_in_mem_space
+ ? (rw_read_not_write
+ ? ~delay_done
+ : 1'b0)
+ : ~delay_done) | reset;
+
+ reg ignore_after_delay = 0;
+
+ reg [31:0] io_read_output_register;
+ reg last_read_was_ram;
+
+ assign rw_data_out = last_read_was_ram ? ram_a_read_output : io_read_output_register;
+
+ reg [7:0] gpio_input_sync_first = 0;
+ reg [7:0] gpio_input = 0;
+ always @(posedge clk) gpio_input_sync_first <= {5'b0, ~switch_3, ~switch_2, 1'b0};
+ always @(posedge clk) gpio_input <= gpio_input_sync_first;
+ reg [7:0] gpio_output = 0;
+ assign led_1 = ~gpio_output[0];
+ assign led_3 = ~gpio_output[2];
+
+ always @(posedge clk or posedge reset) begin
+ if(reset) begin
+ delay_done <= 0;
+ tty_write <= 0;
+ ignore_after_delay <= 0;
+ io_read_output_register <= 'hXXXXXXXX;
+ last_read_was_ram <= 1'hX;
+ gpio_output <= 0;
+ end
+ else begin
+ delay_done <= 0;
+ tty_write <= 0;
+ if(ignore_after_delay) begin
+ ignore_after_delay <= 0;
+ end
+ else if(rw_active & rw_address_in_mem_space) begin
+ if(rw_read_not_write) begin
+ delay_done <= 1;
+ ignore_after_delay <= 1;
+ last_read_was_ram <= 1;
+ end
+ else begin
+ last_read_was_ram <= 1;
+ end
+ end
+ else if(rw_active & rw_address_in_io_space) begin
+ if(rw_address_is_tty) begin
+ if(rw_read_not_write) begin
+ last_read_was_ram <= 0;
+ io_read_output_register <= 0;
+ delay_done <= 1;
+ ignore_after_delay <= 1;
+ end
+ else begin
+ if(tty_write_busy) begin
+ delay_done <= 0;
+ end
+ else begin
+ tty_write <= 1;
+ tty_write_data <= rw_data_in[7:0];
+ delay_done <= 1;
+ ignore_after_delay <= 1;
+ end
+ last_read_was_ram <= 0;
+ io_read_output_register <= 'hXXXXXXXX;
+ end
+ end
+ else if(rw_address_is_gpio) begin
+ if(rw_read_not_write) begin
+ last_read_was_ram <= 0;
+ io_read_output_register <= {16'b0, gpio_input, gpio_output};
+ delay_done <= 1;
+ ignore_after_delay <= 1;
+ end
+ else begin
+ if(rw_byte_mask[0])
+ gpio_output <= rw_data_in[7:0];
+ delay_done <= 1;
+ ignore_after_delay <= 1;
+ last_read_was_ram <= 0;
+ io_read_output_register <= 'hXXXXXXXX;
+ end
+ end
+ else begin
+ //TODO finish implementing I/O
+ last_read_was_ram <= 0;
+ io_read_output_register <= 'hXXXXXXXX;
+ end
+ end
+ else begin
+ last_read_was_ram <= 0;
+ io_read_output_register <= 'hXXXXXXXX;
+ end
+ end
+ end
+
+endmodule
--- /dev/null
+7F 41 61 51 4B 45 7F 00
+7E 81 A5 81 BD 99 81 7E
+7E FF DB FF C3 E7 FF 7E
+36 7F 7F 7F 3E 1C 08 00
+08 1C 3E 7F 3E 1C 08 00
+1C 3E 1C 7F 7F 3E 1C 3E
+08 08 1C 3E 7F 3E 1C 3E
+00 00 18 3C 3C 18 00 00
+FF FF E7 C3 C3 E7 FF FF
+00 3C 66 42 42 66 3C 00
+FF C3 99 BD BD 99 C3 FF
+F0 E0 F0 BE 33 33 33 1E
+3C 66 66 66 3C 18 7E 18
+FC CC FC 0C 0C 0E 0F 07
+FE C6 FE C6 C6 E6 67 03
+99 5A 3C E7 E7 3C 5A 99
+01 07 1F 7F 1F 07 01 00
+40 70 7C 7F 7C 70 40 00
+18 3C 7E 18 18 7E 3C 18
+66 66 66 66 66 00 66 00
+FE DB DB DE D8 D8 D8 00
+7C C6 1C 36 36 1C 33 1E
+00 00 00 00 7E 7E 7E 00
+18 3C 7E 18 7E 3C 18 FF
+18 3C 7E 18 18 18 18 00
+18 18 18 18 7E 3C 18 00
+00 18 30 7F 30 18 00 00
+00 0C 06 7F 06 0C 00 00
+00 00 03 03 03 7F 00 00
+00 24 66 FF 66 24 00 00
+00 18 3C 7E FF FF 00 00
+00 FF FF 7E 3C 18 00 00
+00 00 00 00 00 00 00 00
+0C 1E 1E 0C 0C 00 0C 00
+36 36 36 00 00 00 00 00
+36 36 7F 36 7F 36 36 00
+0C 3E 03 1E 30 1F 0C 00
+00 63 33 18 0C 66 63 00
+1C 36 1C 6E 3B 33 6E 00
+06 06 03 00 00 00 00 00
+18 0C 06 06 06 0C 18 00
+06 0C 18 18 18 0C 06 00
+00 66 3C FF 3C 66 00 00
+00 0C 0C 3F 0C 0C 00 00
+00 00 00 00 00 0C 0C 06
+00 00 00 3F 00 00 00 00
+00 00 00 00 00 0C 0C 00
+60 30 18 0C 06 03 01 00
+3E 63 73 7B 6F 67 3E 00
+0C 0E 0C 0C 0C 0C 3F 00
+1E 33 30 1C 06 33 3F 00
+1E 33 30 1C 30 33 1E 00
+38 3C 36 33 7F 30 78 00
+3F 03 1F 30 30 33 1E 00
+1C 06 03 1F 33 33 1E 00
+3F 33 30 18 0C 0C 0C 00
+1E 33 33 1E 33 33 1E 00
+1E 33 33 3E 30 18 0E 00
+00 0C 0C 00 00 0C 0C 00
+00 0C 0C 00 00 0C 0C 06
+18 0C 06 03 06 0C 18 00
+00 00 3F 00 00 3F 00 00
+06 0C 18 30 18 0C 06 00
+1E 33 30 18 0C 00 0C 00
+3E 63 7B 7B 7B 03 1E 00
+0C 1E 33 33 3F 33 33 00
+3F 66 66 3E 66 66 3F 00
+3C 66 03 03 03 66 3C 00
+1F 36 66 66 66 36 1F 00
+7F 46 16 1E 16 46 7F 00
+7F 46 16 1E 16 06 0F 00
+3C 66 03 03 73 66 7C 00
+33 33 33 3F 33 33 33 00
+1E 0C 0C 0C 0C 0C 1E 00
+78 30 30 30 33 33 1E 00
+67 66 36 1E 36 66 67 00
+0F 06 06 06 46 66 7F 00
+63 77 7F 7F 6B 63 63 00
+63 67 6F 7B 73 63 63 00
+1C 36 63 63 63 36 1C 00
+3F 66 66 3E 06 06 0F 00
+1E 33 33 33 3B 1E 38 00
+3F 66 66 3E 36 66 67 00
+1E 33 07 0E 38 33 1E 00
+3F 2D 0C 0C 0C 0C 1E 00
+33 33 33 33 33 33 3F 00
+33 33 33 33 33 1E 0C 00
+63 63 63 6B 7F 77 63 00
+63 63 36 1C 1C 36 63 00
+33 33 33 1E 0C 0C 1E 00
+7F 63 31 18 4C 66 7F 00
+1E 06 06 06 06 06 1E 00
+03 06 0C 18 30 60 40 00
+1E 18 18 18 18 18 1E 00
+08 1C 36 63 00 00 00 00
+00 00 00 00 00 00 00 FF
+0C 0C 18 00 00 00 00 00
+00 00 1E 30 3E 33 6E 00
+07 06 06 3E 66 66 3B 00
+00 00 1E 33 03 33 1E 00
+38 30 30 3E 33 33 6E 00
+00 00 1E 33 3F 03 1E 00
+1C 36 06 0F 06 06 0F 00
+00 00 6E 33 33 3E 30 1F
+07 06 36 6E 66 66 67 00
+0C 00 0E 0C 0C 0C 1E 00
+30 00 30 30 30 33 33 1E
+07 06 66 36 1E 36 67 00
+0E 0C 0C 0C 0C 0C 1E 00
+00 00 33 7F 7F 6B 63 00
+00 00 1F 33 33 33 33 00
+00 00 1E 33 33 33 1E 00
+00 00 3B 66 66 3E 06 0F
+00 00 6E 33 33 3E 30 78
+00 00 3B 6E 66 06 0F 00
+00 00 3E 03 1E 30 1F 00
+08 0C 3E 0C 0C 2C 18 00
+00 00 33 33 33 33 6E 00
+00 00 33 33 33 1E 0C 00
+00 00 63 6B 7F 7F 36 00
+00 00 63 36 1C 36 63 00
+00 00 33 33 33 3E 30 1F
+00 00 3F 19 0C 26 3F 00
+38 0C 0C 07 0C 0C 38 00
+18 18 18 00 18 18 18 00
+07 0C 0C 38 0C 0C 07 00
+6E 3B 00 00 00 00 00 00
+00 08 1C 36 63 63 7F 00
+1E 33 03 33 1E 18 30 1E
+00 33 00 33 33 33 7E 00
+38 00 1E 33 3F 03 1E 00
+7E C3 3C 60 7C 66 FC 00
+33 00 1E 30 3E 33 7E 00
+07 00 1E 30 3E 33 7E 00
+0C 0C 1E 30 3E 33 7E 00
+00 00 1E 03 03 1E 30 1C
+7E C3 3C 66 7E 06 3C 00
+33 00 1E 33 3F 03 1E 00
+07 00 1E 33 3F 03 1E 00
+33 00 0E 0C 0C 0C 1E 00
+3E 63 1C 18 18 18 3C 00
+07 00 0E 0C 0C 0C 1E 00
+63 1C 36 63 7F 63 63 00
+0C 0C 00 1E 33 3F 33 00
+38 00 3F 06 1E 06 3F 00
+00 00 FE 30 FE 33 FE 00
+7C 36 33 7F 33 33 73 00
+1E 33 00 1E 33 33 1E 00
+00 33 00 1E 33 33 1E 00
+00 07 00 1E 33 33 1E 00
+1E 33 00 33 33 33 7E 00
+00 07 00 33 33 33 7E 00
+00 33 00 33 33 3E 30 1F
+C3 18 3C 66 66 3C 18 00
+33 00 33 33 33 33 1E 00
+18 18 7E 03 03 7E 18 18
+1C 36 26 0F 06 67 3F 00
+33 33 1E 3F 0C 3F 0C 0C
+1F 33 33 5F 63 F3 63 E3
+70 D8 18 3C 18 18 1B 0E
+38 00 1E 30 3E 33 7E 00
+1C 00 0E 0C 0C 0C 1E 00
+00 38 00 1E 33 33 1E 00
+00 38 00 33 33 33 7E 00
+00 1F 00 1F 33 33 33 00
+3F 00 33 37 3F 3B 33 00
+3C 36 36 7C 00 7E 00 00
+1C 36 36 1C 00 3E 00 00
+0C 00 0C 06 03 33 1E 00
+00 00 00 3F 03 03 00 00
+00 00 00 3F 30 30 00 00
+C3 63 33 7B CC 66 33 F0
+C3 63 33 DB EC F6 F3 C0
+18 18 00 18 18 18 18 00
+00 CC 66 33 66 CC 00 00
+00 33 66 CC 66 33 00 00
+44 11 44 11 44 11 44 11
+AA 55 AA 55 AA 55 AA 55
+DB EE DB 77 DB EE DB 77
+18 18 18 18 18 18 18 18
+18 18 18 18 1F 18 18 18
+18 18 1F 18 1F 18 18 18
+6C 6C 6C 6C 6F 6C 6C 6C
+00 00 00 00 7F 6C 6C 6C
+00 00 1F 18 1F 18 18 18
+6C 6C 6F 60 6F 6C 6C 6C
+6C 6C 6C 6C 6C 6C 6C 6C
+00 00 7F 60 6F 6C 6C 6C
+6C 6C 6F 60 7F 00 00 00
+6C 6C 6C 6C 7F 00 00 00
+18 18 1F 18 1F 00 00 00
+00 00 00 00 1F 18 18 18
+18 18 18 18 F8 00 00 00
+18 18 18 18 FF 00 00 00
+00 00 00 00 FF 18 18 18
+18 18 18 18 F8 18 18 18
+00 00 00 00 FF 00 00 00
+18 18 18 18 FF 18 18 18
+18 18 F8 18 F8 18 18 18
+6C 6C 6C 6C EC 6C 6C 6C
+6C 6C EC 0C FC 00 00 00
+00 00 FC 0C EC 6C 6C 6C
+6C 6C EF 00 FF 00 00 00
+00 00 FF 00 EF 6C 6C 6C
+6C 6C EC 0C EC 6C 6C 6C
+00 00 FF 00 FF 00 00 00
+6C 6C EF 00 EF 6C 6C 6C
+18 18 FF 00 FF 00 00 00
+6C 6C 6C 6C FF 00 00 00
+00 00 FF 00 FF 18 18 18
+00 00 00 00 FF 6C 6C 6C
+6C 6C 6C 6C FC 00 00 00
+18 18 F8 18 F8 00 00 00
+00 00 F8 18 F8 18 18 18
+00 00 00 00 FC 6C 6C 6C
+6C 6C 6C 6C FF 6C 6C 6C
+18 18 FF 18 FF 18 18 18
+18 18 18 18 1F 00 00 00
+00 00 00 00 F8 18 18 18
+FF FF FF FF FF FF FF FF
+00 00 00 00 FF FF FF FF
+0F 0F 0F 0F 0F 0F 0F 0F
+F0 F0 F0 F0 F0 F0 F0 F0
+FF FF FF FF 00 00 00 00
+00 00 6E 3B 13 3B 6E 00
+00 1E 33 1F 33 1F 03 03
+00 3F 33 03 03 03 03 00
+00 7F 36 36 36 36 36 00
+3F 33 06 0C 06 33 3F 00
+00 00 7E 1B 1B 1B 0E 00
+00 66 66 66 66 3E 06 03
+00 6E 3B 18 18 18 18 00
+3F 0C 1E 33 33 1E 0C 3F
+1C 36 63 7F 63 36 1C 00
+1C 36 63 63 36 36 77 00
+38 0C 18 3E 33 33 1E 00
+00 00 7E DB DB 7E 00 00
+60 30 7E DB DB 7E 06 03
+1C 06 03 1F 03 06 1C 00
+1E 33 33 33 33 33 33 00
+00 3F 00 3F 00 3F 00 00
+0C 0C 3F 0C 0C 00 3F 00
+06 0C 18 0C 06 00 3F 00
+18 0C 06 0C 18 00 3F 00
+70 D8 D8 18 18 18 18 18
+18 18 18 18 18 1B 1B 0E
+0C 0C 00 3F 00 0C 0C 00
+00 6E 3B 00 6E 3B 00 00
+1C 36 36 1C 00 00 00 00
+00 00 00 18 18 00 00 00
+00 00 00 00 18 00 00 00
+F0 30 30 30 37 36 3C 38
+1E 36 36 36 36 00 00 00
+0E 18 0C 06 1E 00 00 00
+00 00 3C 3C 3C 3C 00 00
+7F 41 41 41 41 41 7F 00
--- /dev/null
+NET "clk" LOC = A10;
+
+NET "vga_hsync" SLEW = FAST;
+NET "vga_vsync" SLEW = FAST;
+
+NET "vga_hsync" LOC = A14;
+NET "vga_vsync" LOC = B14;
+
+NET "vga_r[0]" SLEW = FAST;
+NET "vga_r[1]" SLEW = FAST;
+NET "vga_r[2]" SLEW = FAST;
+NET "vga_r[3]" SLEW = FAST;
+NET "vga_r[4]" SLEW = FAST;
+NET "vga_r[5]" SLEW = FAST;
+NET "vga_r[6]" SLEW = FAST;
+NET "vga_r[7]" SLEW = FAST;
+
+NET "vga_r[0]" LOC = R12;
+NET "vga_r[1]" LOC = T12;
+NET "vga_r[2]" LOC = T14;
+NET "vga_r[3]" LOC = T13;
+NET "vga_r[4]" LOC = T15;
+NET "vga_r[5]" LOC = R14;
+NET "vga_r[6]" LOC = R16;
+NET "vga_r[7]" LOC = R15;
+
+NET "vga_g[0]" SLEW = FAST;
+NET "vga_g[1]" SLEW = FAST;
+NET "vga_g[2]" SLEW = FAST;
+NET "vga_g[3]" SLEW = FAST;
+NET "vga_g[4]" SLEW = FAST;
+NET "vga_g[5]" SLEW = FAST;
+NET "vga_g[6]" SLEW = FAST;
+NET "vga_g[7]" SLEW = FAST;
+
+NET "vga_g[0]" LOC = P16;
+NET "vga_g[1]" LOC = P15;
+NET "vga_g[2]" LOC = L13;
+NET "vga_g[3]" LOC = L12;
+NET "vga_g[4]" LOC = M14;
+NET "vga_g[5]" LOC = M13;
+NET "vga_g[6]" LOC = N16;
+NET "vga_g[7]" LOC = N14;
+
+NET "vga_b[0]" SLEW = FAST;
+NET "vga_b[1]" SLEW = FAST;
+NET "vga_b[2]" SLEW = FAST;
+NET "vga_b[3]" SLEW = FAST;
+NET "vga_b[4]" SLEW = FAST;
+NET "vga_b[5]" SLEW = FAST;
+NET "vga_b[6]" SLEW = FAST;
+NET "vga_b[7]" SLEW = FAST;
+
+NET "vga_b[0]" LOC = M15;
+NET "vga_b[1]" LOC = K12;
+NET "vga_b[2]" LOC = K11;
+NET "vga_b[3]" LOC = L14;
+NET "vga_b[4]" LOC = L16;
+NET "vga_b[5]" LOC = K16;
+NET "vga_b[6]" LOC = K15;
+NET "vga_b[7]" LOC = J13;
+
+NET "vga_pixel_clock" LOC = K14;
+
+NET "vga_pixel_clock" SLEW = FAST;
+
+NET "vga_blank" LOC = M16;
+
+NET "vga_blank" SLEW = FAST;
+
+NET "clk" TNM_NET = "clk";
+TIMESPEC TS_clk = PERIOD "clk" 20 ns HIGH 50 %;
+
+INST "cpu1/memory_interface/ram/ram_0_byte0/Mram_ram" LOC = RAMB16_X0Y30;
+INST "cpu1/memory_interface/ram/ram_0_byte1/Mram_ram" LOC = RAMB16_X0Y22;
+INST "cpu1/memory_interface/ram/ram_0_byte2/Mram_ram" LOC = RAMB16_X1Y30;
+INST "cpu1/memory_interface/ram/ram_0_byte3/Mram_ram" LOC = RAMB16_X1Y22;
+INST "cpu1/memory_interface/ram/ram_1_byte0/Mram_ram" LOC = RAMB16_X0Y28;
+INST "cpu1/memory_interface/ram/ram_1_byte1/Mram_ram" LOC = RAMB16_X0Y20;
+INST "cpu1/memory_interface/ram/ram_1_byte2/Mram_ram" LOC = RAMB16_X1Y28;
+INST "cpu1/memory_interface/ram/ram_1_byte3/Mram_ram" LOC = RAMB16_X1Y20;
+INST "cpu1/memory_interface/ram/ram_2_byte0/Mram_ram" LOC = RAMB16_X0Y26;
+INST "cpu1/memory_interface/ram/ram_2_byte1/Mram_ram" LOC = RAMB16_X0Y18;
+INST "cpu1/memory_interface/ram/ram_2_byte2/Mram_ram" LOC = RAMB16_X1Y26;
+INST "cpu1/memory_interface/ram/ram_2_byte3/Mram_ram" LOC = RAMB16_X1Y18;
+INST "cpu1/memory_interface/ram/ram_3_byte0/Mram_ram" LOC = RAMB16_X0Y24;
+INST "cpu1/memory_interface/ram/ram_3_byte1/Mram_ram" LOC = RAMB16_X0Y16;
+INST "cpu1/memory_interface/ram/ram_3_byte2/Mram_ram" LOC = RAMB16_X1Y24;
+INST "cpu1/memory_interface/ram/ram_3_byte3/Mram_ram" LOC = RAMB16_X1Y16;
+
+NET "switch_2" LOC = T8;
+NET "switch_3" LOC = R7;
+NET "led_1" LOC = T9;
+NET "led_3" LOC = R9;
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 100ps
+
+module main(
+ input clk,
+ output [7:0] vga_r,
+ output [7:0] vga_g,
+ output [7:0] vga_b,
+ output vga_hsync,
+ output vga_vsync,
+ output vga_blank,
+ output vga_pixel_clock,
+ input switch_2,
+ input switch_3,
+ output led_1,
+ output led_3
+ );
+
+ wire tty_write;
+ wire [7:0] tty_write_data;
+ wire tty_write_busy;
+ reg reset = 1;
+
+ vga vga1(
+ .clk(clk),
+ .vga_r(vga_r),
+ .vga_g(vga_g),
+ .vga_b(vga_b),
+ .vga_hsync(vga_hsync),
+ .vga_vsync(vga_vsync),
+ .vga_blank(vga_blank),
+ .vga_pixel_clock(vga_pixel_clock),
+ .tty_write(tty_write),
+ .tty_data(tty_write_data),
+ .tty_busy(tty_write_busy)
+ );
+
+ cpu cpu1(
+ .clk(clk),
+ .reset(reset),
+ .tty_write(tty_write),
+ .tty_write_data(tty_write_data),
+ .tty_write_busy(tty_write_busy),
+ .switch_2(switch_2),
+ .switch_3(switch_3),
+ .led_1(led_1),
+ .led_3(led_3)
+ );
+
+ reg [31:0] reset_counter = 256;
+
+ always @(posedge clk)
+ if(reset_counter == 0)
+ reset <= 0;
+ else
+ reset_counter <= reset_counter - 1;
+
+endmodule
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 100ps
+
+module main_test;
+
+ // Inputs
+ reg clk;
+
+ // Outputs
+ wire [7:0] vga_r;
+ wire [7:0] vga_g;
+ wire [7:0] vga_b;
+ wire vga_hsync;
+ wire vga_vsync;
+ wire vga_blank;
+ wire vga_pixel_clock;
+
+ // Instantiate the Unit Under Test (UUT)
+ main uut (
+ .clk(clk),
+ .vga_r(vga_r),
+ .vga_g(vga_g),
+ .vga_b(vga_b),
+ .vga_hsync(vga_hsync),
+ .vga_vsync(vga_vsync),
+ .vga_blank(vga_blank),
+ .vga_pixel_clock(vga_pixel_clock)
+ );
+
+ initial begin
+ // Initialize Inputs
+ clk = 0;
+
+ // Add stimulus here
+
+ forever #10 clk = ~clk;
+ end
+
+ reg [7:0] r;
+ reg [7:0] g;
+ reg [7:0] b;
+
+ always @(posedge vga_pixel_clock) begin
+ r = vga_r;
+ g = vga_g;
+ b = vga_b;
+ end
+
+endmodule
+
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`ifndef riscv_vh_
+`define riscv_vh_
+
+`define cause_instruction_address_misaligned 'h0
+`define cause_instruction_access_fault 'h1
+`define cause_illegal_instruction 'h2
+`define cause_breakpoint 'h3
+`define cause_load_address_misaligned 'h4
+`define cause_load_access_fault 'h5
+`define cause_store_amo_address_misaligned 'h6
+`define cause_store_amo_access_fault 'h7
+`define cause_user_environment_call 'h8
+`define cause_supervisor_environment_call 'h9
+`define cause_machine_environment_call 'hB
+`define cause_instruction_page_fault 'hC
+`define cause_load_page_fault 'hD
+`define cause_store_amo_page_fault 'hF
+
+`define opcode_load 7'h03
+`define opcode_load_fp 7'h07
+`define opcode_custom_0 7'h0B
+`define opcode_misc_mem 7'h0F
+`define opcode_op_imm 7'h13
+`define opcode_auipc 7'h17
+`define opcode_op_imm_32 7'h1B
+`define opcode_48b_escape_0 7'h1F
+
+`define opcode_store 7'h23
+`define opcode_store_fp 7'h27
+`define opcode_custom_1 7'h2B
+`define opcode_amo 7'h2F
+`define opcode_op 7'h33
+`define opcode_lui 7'h37
+`define opcode_op_32 7'h3B
+`define opcode_64b_escape 7'h3F
+
+`define opcode_madd 7'h43
+`define opcode_msub 7'h47
+`define opcode_nmsub 7'h4B
+`define opcode_nmadd 7'h4F
+`define opcode_op_fp 7'h53
+`define opcode_reserved_10101 7'h57
+`define opcode_rv128_0 7'h5B
+`define opcode_48b_escape_1 7'h5F
+
+`define opcode_branch 7'h63
+`define opcode_jalr 7'h67
+`define opcode_reserved_11010 7'h6B
+`define opcode_jal 7'h6F
+`define opcode_system 7'h73
+`define opcode_reserved_11101 7'h77
+`define opcode_rv128_1 7'h7B
+`define opcode_80b_escape 7'h7F
+
+`define funct3_jalr 3'h0
+`define funct3_beq 3'h0
+`define funct3_bne 3'h1
+`define funct3_blt 3'h4
+`define funct3_bge 3'h5
+`define funct3_bltu 3'h6
+`define funct3_bgeu 3'h7
+`define funct3_lb 3'h0
+`define funct3_lh 3'h1
+`define funct3_lw 3'h2
+`define funct3_lbu 3'h4
+`define funct3_lhu 3'h5
+`define funct3_sb 3'h0
+`define funct3_sh 3'h1
+`define funct3_sw 3'h2
+`define funct3_addi 3'h0
+`define funct3_slli 3'h1
+`define funct3_slti 3'h2
+`define funct3_sltiu 3'h3
+`define funct3_xori 3'h4
+`define funct3_srli_srai 3'h5
+`define funct3_ori 3'h6
+`define funct3_andi 3'h7
+`define funct3_add_sub 3'h0
+`define funct3_sll 3'h1
+`define funct3_slt 3'h2
+`define funct3_sltu 3'h3
+`define funct3_xor 3'h4
+`define funct3_srl_sra 3'h5
+`define funct3_or 3'h6
+`define funct3_and 3'h7
+`define funct3_fence 3'h0
+`define funct3_fence_i 3'h1
+`define funct3_ecall_ebreak 3'h0
+`define funct3_csrrw 3'h1
+`define funct3_csrrs 3'h2
+`define funct3_csrrc 3'h3
+`define funct3_csrrwi 3'h5
+`define funct3_csrrsi 3'h6
+`define funct3_csrrci 3'h7
+
+`define csr_ustatus 12'h000
+`define csr_fflags 12'h001
+`define csr_frm 12'h002
+`define csr_fcsr 12'h003
+`define csr_uie 12'h004
+`define csr_utvec 12'h005
+`define csr_uscratch 12'h040
+`define csr_uepc 12'h041
+`define csr_ucause 12'h042
+`define csr_utval 12'h043
+`define csr_uip 12'h044
+`define csr_cycle 12'hC00
+`define csr_time 12'hC01
+`define csr_instret 12'hC02
+`define csr_cycleh 12'hC80
+`define csr_timeh 12'hC81
+`define csr_instreth 12'hC82
+
+`define csr_sstatus 12'h100
+`define csr_sedeleg 12'h102
+`define csr_sideleg 12'h103
+`define csr_sie 12'h104
+`define csr_stvec 12'h105
+`define csr_scounteren 12'h106
+`define csr_sscratch 12'h140
+`define csr_sepc 12'h141
+`define csr_scause 12'h142
+`define csr_stval 12'h143
+`define csr_sip 12'h144
+`define csr_satp 12'h180
+
+`define csr_mvendorid 12'hF11
+`define csr_marchid 12'hF12
+`define csr_mimpid 12'hF13
+`define csr_mhartid 12'hF14
+`define csr_mstatus 12'h300
+`define csr_misa 12'h301
+`define csr_medeleg 12'h302
+`define csr_mideleg 12'h303
+`define csr_mie 12'h304
+`define csr_mtvec 12'h305
+`define csr_mcounteren 12'h306
+`define csr_mscratch 12'h340
+`define csr_mepc 12'h341
+`define csr_mcause 12'h342
+`define csr_mtval 12'h343
+`define csr_mip 12'h344
+`define csr_mcycle 12'hB00
+`define csr_minstret 12'hB02
+`define csr_mcycleh 12'hB80
+`define csr_minstreth 12'hB82
+
+`define csr_dcsr 12'h7B0
+`define csr_dpc 12'h7B1
+`define csr_dscratch 12'h7B2
+
+`endif
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
+
+ <header>
+ <!-- ISE source project file created by Project Navigator. -->
+ <!-- -->
+ <!-- This file contains project source information including a list of -->
+ <!-- project source files, project and process properties. This file, -->
+ <!-- along with the project source files, is sufficient to open and -->
+ <!-- implement in ISE Project Navigator. -->
+ <!-- -->
+ <!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
+ </header>
+
+ <version xil_pn:ise_version="14.7" xil_pn:schema_version="2"/>
+
+ <files>
+ <file xil_pn:name="main.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="13"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="13"/>
+ </file>
+ <file xil_pn:name="vga.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="11"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="11"/>
+ </file>
+ <file xil_pn:name="main.ucf" xil_pn:type="FILE_UCF">
+ <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
+ </file>
+ <file xil_pn:name="font8x8.hex" xil_pn:type="FILE_IMPACT_MISC"/>
+ <file xil_pn:name="vga_clock_generator.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="6"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="6"/>
+ </file>
+ <file xil_pn:name="vga_location_generator.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="4"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="4"/>
+ </file>
+ <file xil_pn:name="vga_text_buffer.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="3"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="3"/>
+ </file>
+ <file xil_pn:name="vga_font_generator.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="5"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="5"/>
+ </file>
+ <file xil_pn:name="main_test.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="14"/>
+ <association xil_pn:name="PostMapSimulation" xil_pn:seqID="106"/>
+ <association xil_pn:name="PostRouteSimulation" xil_pn:seqID="106"/>
+ <association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="106"/>
+ </file>
+ <file xil_pn:name="text_initial.hex" xil_pn:type="FILE_IMPACT_MISC"/>
+ <file xil_pn:name="cpu.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="12"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="12"/>
+ </file>
+ <file xil_pn:name="cpu_memory_interface.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="7"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="7"/>
+ </file>
+ <file xil_pn:name="block_memory.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="2"/>
+ </file>
+ <file xil_pn:name="cpu_alu.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="10"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="10"/>
+ </file>
+ <file xil_pn:name="cpu_fetch_stage.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="8"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="8"/>
+ </file>
+ <file xil_pn:name="cpu_decoder.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="9"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="9"/>
+ </file>
+ <file xil_pn:name="cpu.bmm" xil_pn:type="FILE_BMM">
+ <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
+ </file>
+ <file xil_pn:name="block_memory_16kbit.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="1"/>
+ </file>
+ </files>
+
+ <properties>
+ <property xil_pn:name="AES Initial Vector spartan6" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="AES Key (Hex String) spartan6" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Add I/O Buffers" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Allow Logic Optimization Across Hierarchy" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Allow SelectMAP Pins to Persist" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Allow Unexpanded Blocks" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Allow Unmatched LOC Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Allow Unmatched Timing Group Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Analysis Effort Level" xil_pn:value="Standard" xil_pn:valueState="default"/>
+ <property xil_pn:name="Asynchronous To Synchronous" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Auto Implementation Compile Order" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Auto Implementation Top" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Automatic BRAM Packing" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Automatically Insert glbl Module in the Netlist" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Automatically Run Generate Target PROM/ACE File" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="BRAM Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
+ <property xil_pn:name="Bring Out Global Set/Reset Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Bring Out Global Tristate Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Bus Delimiter" xil_pn:value="<>" xil_pn:valueState="default"/>
+ <property xil_pn:name="Case" xil_pn:value="Maintain" xil_pn:valueState="default"/>
+ <property xil_pn:name="Case Implementation Style" xil_pn:value="None" xil_pn:valueState="default"/>
+ <property xil_pn:name="Change Device Speed To" xil_pn:value="-2" xil_pn:valueState="default"/>
+ <property xil_pn:name="Change Device Speed To Post Trace" xil_pn:value="-2" xil_pn:valueState="default"/>
+ <property xil_pn:name="Combinatorial Logic Optimization" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Compile EDK Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Compile SIMPRIM (Timing) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Compile UNISIM (Functional) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Compile XilinxCoreLib (CORE Generator) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Compile for HDL Debugging" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Configuration Clk (Configuration Pins)" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
+ <property xil_pn:name="Configuration Pin Done" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
+ <property xil_pn:name="Configuration Pin M0" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
+ <property xil_pn:name="Configuration Pin M1" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
+ <property xil_pn:name="Configuration Pin M2" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
+ <property xil_pn:name="Configuration Pin Program" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
+ <property xil_pn:name="Configuration Rate spartan6" xil_pn:value="2" xil_pn:valueState="default"/>
+ <property xil_pn:name="Correlate Output to Input Design" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Create ASCII Configuration File" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Create Binary Configuration File" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Create Bit File" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Create I/O Pads from Ports" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Create IEEE 1532 Configuration File spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Create Logic Allocation File" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Create Mask File" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Create ReadBack Data Files" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Cross Clock Analysis" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Custom Waveform Configuration File Behav" xil_pn:value="main_test.wcfg" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="DSP Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
+ <property xil_pn:name="Delay Values To Be Read from SDF" xil_pn:value="Setup Time" xil_pn:valueState="default"/>
+ <property xil_pn:name="Device" xil_pn:value="xc6slx16" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Device Family" xil_pn:value="Spartan6" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Device Speed Grade/Select ABS Minimum" xil_pn:value="-2" xil_pn:valueState="default"/>
+ <property xil_pn:name="Disable Detailed Package Model Insertion" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Do Not Escape Signal and Instance Names in Netlist" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Done (Output Events)" xil_pn:value="Default (4)" xil_pn:valueState="default"/>
+ <property xil_pn:name="Drive Awake Pin During Suspend/Wake Sequence spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Drive Done Pin High" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Enable BitStream Compression" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Enable Cyclic Redundancy Checking (CRC) spartan6" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Enable Debugging of Serial Mode BitStream" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Enable External Master Clock spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Enable Hardware Co-Simulation" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Enable Internal Done Pipe" xil_pn:value="true" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Enable Message Filtering" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Enable Multi-Pin Wake-Up Suspend Mode spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Enable Multi-Threading" xil_pn:value="2" xil_pn:valueState="non-default" xil_pn:x_locked="true"/>
+ <property xil_pn:name="Enable Multi-Threading par spartan6" xil_pn:value="2" xil_pn:valueState="non-default" xil_pn:x_locked="true"/>
+ <property xil_pn:name="Enable Outputs (Output Events)" xil_pn:value="Default (5)" xil_pn:valueState="default"/>
+ <property xil_pn:name="Enable Suspend/Wake Global Set/Reset spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Encrypt Bitstream spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Encrypt Key Select spartan6" xil_pn:value="BBRAM" xil_pn:valueState="default"/>
+ <property xil_pn:name="Equivalent Register Removal Map" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Equivalent Register Removal XST" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Essential Bits" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Evaluation Development Board" xil_pn:value="None Specified" xil_pn:valueState="default"/>
+ <property xil_pn:name="Exclude Compilation of Deprecated EDK Cores" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Exclude Compilation of EDK Sub-Libraries" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Extra Cost Tables Map" xil_pn:value="0" xil_pn:valueState="default"/>
+ <property xil_pn:name="Extra Effort (Highest PAR level only)" xil_pn:value="None" xil_pn:valueState="default"/>
+ <property xil_pn:name="FPGA Start-Up Clock" xil_pn:value="CCLK" xil_pn:valueState="default"/>
+ <property xil_pn:name="FSM Encoding Algorithm" xil_pn:value="Auto" xil_pn:valueState="default"/>
+ <property xil_pn:name="FSM Style" xil_pn:value="LUT" xil_pn:valueState="default"/>
+ <property xil_pn:name="Filter Files From Compile Order" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Flatten Output Netlist" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Functional Model Target Language ArchWiz" xil_pn:value="Verilog" xil_pn:valueState="default"/>
+ <property xil_pn:name="Functional Model Target Language Coregen" xil_pn:value="Verilog" xil_pn:valueState="default"/>
+ <property xil_pn:name="Functional Model Target Language Schematic" xil_pn:value="Verilog" xil_pn:valueState="default"/>
+ <property xil_pn:name="GTS Cycle During Suspend/Wakeup Sequence spartan6" xil_pn:value="4" xil_pn:valueState="default"/>
+ <property xil_pn:name="GWE Cycle During Suspend/Wakeup Sequence spartan6" xil_pn:value="5" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Architecture Only (No Entity Declaration)" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Asynchronous Delay Report" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Clock Region Report" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Constraints Interaction Report" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Constraints Interaction Report Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Datasheet Section" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Datasheet Section Post Trace" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Detailed MAP Report" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Multiple Hierarchical Netlist Files" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Post-Place & Route Power Report" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Post-Place & Route Simulation Model" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate RTL Schematic" xil_pn:value="Yes" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate SAIF File for Power Optimization/Estimation Par" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Testbench File" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Timegroups Section" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generate Timegroups Section Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Generics, Parameters" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Global Optimization Goal" xil_pn:value="AllClockNets" xil_pn:valueState="default"/>
+ <property xil_pn:name="Global Optimization map spartan6" xil_pn:value="Off" xil_pn:valueState="default"/>
+ <property xil_pn:name="Global Set/Reset Port Name" xil_pn:value="GSR_PORT" xil_pn:valueState="default"/>
+ <property xil_pn:name="Global Tristate Port Name" xil_pn:value="GTS_PORT" xil_pn:valueState="default"/>
+ <property xil_pn:name="Hierarchy Separator" xil_pn:value="/" xil_pn:valueState="default"/>
+ <property xil_pn:name="ISim UUT Instance Name" xil_pn:value="UUT" xil_pn:valueState="default"/>
+ <property xil_pn:name="Ignore User Timing Constraints Map" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Ignore User Timing Constraints Par" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Implementation Top" xil_pn:value="Module|main" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Implementation Top File" xil_pn:value="main.v" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Implementation Top Instance Path" xil_pn:value="/main" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Include 'uselib Directive in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Include SIMPRIM Models in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Include UNISIM Models in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Include sdf_annotate task in Verilog File" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Incremental Compilation" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Insert Buffers to Prevent Pulse Swallowing" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Instantiation Template Target Language Xps" xil_pn:value="Verilog" xil_pn:valueState="default"/>
+ <property xil_pn:name="JTAG Pin TCK" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
+ <property xil_pn:name="JTAG Pin TDI" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
+ <property xil_pn:name="JTAG Pin TDO" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
+ <property xil_pn:name="JTAG Pin TMS" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
+ <property xil_pn:name="Keep Hierarchy" xil_pn:value="No" xil_pn:valueState="default"/>
+ <property xil_pn:name="LUT Combining Map" xil_pn:value="Off" xil_pn:valueState="default"/>
+ <property xil_pn:name="LUT Combining Xst" xil_pn:value="Auto" xil_pn:valueState="default"/>
+ <property xil_pn:name="Language" xil_pn:value="VHDL" xil_pn:valueState="default"/>
+ <property xil_pn:name="Last Applied Goal" xil_pn:value="Minimum Runtime" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Last Applied Strategy" xil_pn:value="Runtime Strategy 1;/opt/Xilinx/14.7/ISE_DS/ISE/spartan6/data/spartan6_runtime.xds" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Last Unlock Status" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Launch SDK after Export" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Library for Verilog Sources" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Load glbl" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Manual Implementation Compile Order" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Map Slice Logic into Unused Block RAMs" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Mask Pins for Multi-Pin Wake-Up Suspend Mode spartan6" xil_pn:value="0x00" xil_pn:valueState="default"/>
+ <property xil_pn:name="Max Fanout" xil_pn:value="100000" xil_pn:valueState="default"/>
+ <property xil_pn:name="Maximum Compression" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Maximum Number of Lines in Report" xil_pn:value="1000" xil_pn:valueState="default"/>
+ <property xil_pn:name="Maximum Signal Name Length" xil_pn:value="20" xil_pn:valueState="default"/>
+ <property xil_pn:name="Move First Flip-Flop Stage" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Move Last Flip-Flop Stage" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="MultiBoot: Insert IPROG CMD in the Bitfile spartan6" xil_pn:value="Enable" xil_pn:valueState="default"/>
+ <property xil_pn:name="MultiBoot: Next Configuration Mode spartan6" xil_pn:value="001" xil_pn:valueState="default"/>
+ <property xil_pn:name="MultiBoot: Starting Address for Golden Configuration spartan6" xil_pn:value="0x00000000" xil_pn:valueState="default"/>
+ <property xil_pn:name="MultiBoot: Starting Address for Next Configuration spartan6" xil_pn:value="0x00000000" xil_pn:valueState="default"/>
+ <property xil_pn:name="MultiBoot: Use New Mode for Next Configuration spartan6" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="MultiBoot: User-Defined Register for Failsafe Scheme spartan6" xil_pn:value="0x0000" xil_pn:valueState="default"/>
+ <property xil_pn:name="Netlist Hierarchy" xil_pn:value="As Optimized" xil_pn:valueState="default"/>
+ <property xil_pn:name="Netlist Translation Type" xil_pn:value="Timestamp" xil_pn:valueState="default"/>
+ <property xil_pn:name="Number of Clock Buffers" xil_pn:value="16" xil_pn:valueState="default"/>
+ <property xil_pn:name="Number of Paths in Error/Verbose Report" xil_pn:value="3" xil_pn:valueState="default"/>
+ <property xil_pn:name="Number of Paths in Error/Verbose Report Post Trace" xil_pn:value="3" xil_pn:valueState="default"/>
+ <property xil_pn:name="Optimization Effort spartan6" xil_pn:value="High" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Optimization Goal" xil_pn:value="Speed" xil_pn:valueState="default"/>
+ <property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Bitgen Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Bitgen Command Line Options spartan6" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Compiler Options" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Compiler Options Map" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Compiler Options Par" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Compiler Options Translate" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Compxlib Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Map Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other NETGEN Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Ngdbuild Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Place & Route Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Simulator Commands Behavioral" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Simulator Commands Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Simulator Commands Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other Simulator Commands Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other XPWR Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Other XST Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Output Extended Identifiers" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Output File Name" xil_pn:value="main" xil_pn:valueState="default"/>
+ <property xil_pn:name="Overwrite Compiled Libraries" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Pack I/O Registers into IOBs" xil_pn:value="Auto" xil_pn:valueState="default"/>
+ <property xil_pn:name="Pack I/O Registers/Latches into IOBs" xil_pn:value="Off" xil_pn:valueState="default"/>
+ <property xil_pn:name="Package" xil_pn:value="ftg256" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Perform Advanced Analysis" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Perform Advanced Analysis Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Perform Timing-Driven Packing and Placement" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Place & Route Effort Level (Overall)" xil_pn:value="Standard" xil_pn:valueState="non-default" xil_pn:x_locked="true"/>
+ <property xil_pn:name="Place And Route Mode" xil_pn:value="Normal Place and Route" xil_pn:valueState="default"/>
+ <property xil_pn:name="Place MultiBoot Settings into Bitstream spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Placer Effort Level Map" xil_pn:value="Standard" xil_pn:valueState="non-default" xil_pn:x_locked="true"/>
+ <property xil_pn:name="Placer Extra Effort Map" xil_pn:value="None" xil_pn:valueState="default"/>
+ <property xil_pn:name="Port to be used" xil_pn:value="Auto - default" xil_pn:valueState="default"/>
+ <property xil_pn:name="Post Map Simulation Model Name" xil_pn:value="main_map.v" xil_pn:valueState="default"/>
+ <property xil_pn:name="Post Place & Route Simulation Model Name" xil_pn:value="main_timesim.v" xil_pn:valueState="default"/>
+ <property xil_pn:name="Post Synthesis Simulation Model Name" xil_pn:value="main_synthesis.v" xil_pn:valueState="default"/>
+ <property xil_pn:name="Post Translate Simulation Model Name" xil_pn:value="main_translate.v" xil_pn:valueState="default"/>
+ <property xil_pn:name="Power Reduction Map spartan6" xil_pn:value="Off" xil_pn:valueState="default"/>
+ <property xil_pn:name="Power Reduction Par" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Power Reduction Xst" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Preferred Language" xil_pn:value="Verilog" xil_pn:valueState="default"/>
+ <property xil_pn:name="Produce Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Project Description" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/>
+ <property xil_pn:name="RAM Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="RAM Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
+ <property xil_pn:name="ROM Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="ROM Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
+ <property xil_pn:name="Read Cores" xil_pn:value="false" xil_pn:valueState="non-default" xil_pn:x_locked="true"/>
+ <property xil_pn:name="Reduce Control Sets" xil_pn:value="Auto" xil_pn:valueState="default"/>
+ <property xil_pn:name="Regenerate Core" xil_pn:value="Under Current Project Setting" xil_pn:valueState="default"/>
+ <property xil_pn:name="Register Balancing" xil_pn:value="No" xil_pn:valueState="default"/>
+ <property xil_pn:name="Register Duplication Map" xil_pn:value="Off" xil_pn:valueState="default"/>
+ <property xil_pn:name="Register Duplication Xst" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Register Ordering spartan6" xil_pn:value="4" xil_pn:valueState="default"/>
+ <property xil_pn:name="Release Write Enable (Output Events)" xil_pn:value="Default (6)" xil_pn:valueState="default"/>
+ <property xil_pn:name="Rename Design Instance in Testbench File to" xil_pn:value="UUT" xil_pn:valueState="default"/>
+ <property xil_pn:name="Rename Top Level Architecture To" xil_pn:value="Structure" xil_pn:valueState="default"/>
+ <property xil_pn:name="Rename Top Level Entity to" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Rename Top Level Module To" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Report Fastest Path(s) in Each Constraint" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Report Fastest Path(s) in Each Constraint Post Trace" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Report Paths by Endpoint" xil_pn:value="3" xil_pn:valueState="default"/>
+ <property xil_pn:name="Report Paths by Endpoint Post Trace" xil_pn:value="3" xil_pn:valueState="default"/>
+ <property xil_pn:name="Report Type" xil_pn:value="Verbose Report" xil_pn:valueState="default"/>
+ <property xil_pn:name="Report Type Post Trace" xil_pn:value="Verbose Report" xil_pn:valueState="default"/>
+ <property xil_pn:name="Report Unconstrained Paths" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Report Unconstrained Paths Post Trace" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Reset On Configuration Pulse Width" xil_pn:value="100" xil_pn:valueState="default"/>
+ <property xil_pn:name="Resource Sharing" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Retain Hierarchy" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Retry Configuration if CRC Error Occurs spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Revision Select" xil_pn:value="00" xil_pn:valueState="default"/>
+ <property xil_pn:name="Revision Select Tristate" xil_pn:value="Disable" xil_pn:valueState="default"/>
+ <property xil_pn:name="Run Design Rules Checker (DRC)" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Run for Specified Time" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Run for Specified Time Map" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Run for Specified Time Par" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Run for Specified Time Translate" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Safe Implementation" xil_pn:value="No" xil_pn:valueState="default"/>
+ <property xil_pn:name="Security" xil_pn:value="Enable Readback and Reconfiguration" xil_pn:valueState="default"/>
+ <property xil_pn:name="Selected Module Instance Name" xil_pn:value="/main_test" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.main_test" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Selected Simulation Root Source Node Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Selected Simulation Root Source Node Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Selected Simulation Source Node" xil_pn:value="UUT" xil_pn:valueState="default"/>
+ <property xil_pn:name="Set SPI Configuration Bus Width spartan6" xil_pn:value="1" xil_pn:valueState="default"/>
+ <property xil_pn:name="Setup External Master Clock Division spartan6" xil_pn:value="1" xil_pn:valueState="default"/>
+ <property xil_pn:name="Shift Register Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Shift Register Minimum Size spartan6" xil_pn:value="2" xil_pn:valueState="default"/>
+ <property xil_pn:name="Show All Models" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Simulation Model Target" xil_pn:value="Verilog" xil_pn:valueState="default"/>
+ <property xil_pn:name="Simulation Run Time ISim" xil_pn:value="30 us" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Simulation Run Time Map" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
+ <property xil_pn:name="Simulation Run Time Par" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
+ <property xil_pn:name="Simulation Run Time Translate" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
+ <property xil_pn:name="Simulator" xil_pn:value="ISim (VHDL/Verilog)" xil_pn:valueState="default"/>
+ <property xil_pn:name="Slice Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
+ <property xil_pn:name="Specify 'define Macro Name and Value" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.main_test" xil_pn:valueState="default"/>
+ <property xil_pn:name="Specify Top Level Instance Names Post-Map" xil_pn:value="Default" xil_pn:valueState="default"/>
+ <property xil_pn:name="Specify Top Level Instance Names Post-Route" xil_pn:value="Default" xil_pn:valueState="default"/>
+ <property xil_pn:name="Specify Top Level Instance Names Post-Translate" xil_pn:value="Default" xil_pn:valueState="default"/>
+ <property xil_pn:name="Speed Grade" xil_pn:value="-2" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Starting Placer Cost Table (1-100) Map spartan6" xil_pn:value="1" xil_pn:valueState="default"/>
+ <property xil_pn:name="Synthesis Tool" xil_pn:value="XST (VHDL/Verilog)" xil_pn:valueState="default"/>
+ <property xil_pn:name="Target Simulator" xil_pn:value="Please Specify" xil_pn:valueState="default"/>
+ <property xil_pn:name="Target UCF File Name" xil_pn:value="main.ucf" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Timing Mode Map" xil_pn:value="Performance Evaluation" xil_pn:valueState="default"/>
+ <property xil_pn:name="Timing Mode Par" xil_pn:value="Performance Evaluation" xil_pn:valueState="default"/>
+ <property xil_pn:name="Top-Level Module Name in Output Netlist" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Top-Level Source Type" xil_pn:value="HDL" xil_pn:valueState="default"/>
+ <property xil_pn:name="Trim Unconnected Signals" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Tristate On Configuration Pulse Width" xil_pn:value="0" xil_pn:valueState="default"/>
+ <property xil_pn:name="Unused IOB Pins" xil_pn:value="Pull Down" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use 64-bit PlanAhead on 64-bit Systems" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Clock Enable" xil_pn:value="Auto" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Custom Project File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Custom Project File Post-Map" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Custom Project File Post-Route" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Custom Project File Post-Translate" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Custom Simulation Command File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Custom Simulation Command File Map" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Custom Simulation Command File Par" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Custom Simulation Command File Translate" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Custom Waveform Configuration File Behav" xil_pn:value="true" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Use Custom Waveform Configuration File Map" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Custom Waveform Configuration File Par" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Custom Waveform Configuration File Translate" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use DSP Block spartan6" xil_pn:value="Auto" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use LOC Constraints" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use RLOC Constraints" xil_pn:value="Yes" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Smart Guide" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Synchronous Reset" xil_pn:value="Auto" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Synchronous Set" xil_pn:value="Auto" xil_pn:valueState="default"/>
+ <property xil_pn:name="Use Synthesis Constraints File" xil_pn:value="true" xil_pn:valueState="default"/>
+ <property xil_pn:name="User Browsed Strategy Files" xil_pn:value="/opt/Xilinx/14.7/ISE_DS/ISE/data/default.xds" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="UserID Code (8 Digit Hexadecimal)" xil_pn:value="0xFFFFFFFF" xil_pn:valueState="default"/>
+ <property xil_pn:name="VCCAUX Voltage Level spartan6" xil_pn:value="2.5V" xil_pn:valueState="default"/>
+ <property xil_pn:name="VHDL Source Analysis Standard" xil_pn:value="VHDL-93" xil_pn:valueState="default"/>
+ <property xil_pn:name="Value Range Check" xil_pn:value="false" xil_pn:valueState="default"/>
+ <property xil_pn:name="Verilog Macros" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="Wait for DCM and PLL Lock (Output Events) spartan6" xil_pn:value="Default (NoWait)" xil_pn:valueState="default"/>
+ <property xil_pn:name="Wakeup Clock spartan6" xil_pn:value="Startup Clock" xil_pn:valueState="default"/>
+ <property xil_pn:name="Watchdog Timer Value spartan6" xil_pn:value="0xFFFF" xil_pn:valueState="default"/>
+ <property xil_pn:name="Working Directory" xil_pn:value="." xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Write Timing Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
+ <!-- -->
+ <!-- The following properties are for internal use only. These should not be modified.-->
+ <!-- -->
+ <property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Module|main_test" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="PROP_DesignName" xil_pn:value="rv32" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="PROP_DevFamilyPMName" xil_pn:value="spartan6" xil_pn:valueState="default"/>
+ <property xil_pn:name="PROP_FPGAConfiguration" xil_pn:value="FPGAConfiguration" xil_pn:valueState="default"/>
+ <property xil_pn:name="PROP_PostMapSimTop" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="PROP_PostParSimTop" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="PROP_PostSynthSimTop" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="PROP_PostXlateSimTop" xil_pn:value="" xil_pn:valueState="default"/>
+ <property xil_pn:name="PROP_PreSynthesis" xil_pn:value="PreSynthesis" xil_pn:valueState="default"/>
+ <property xil_pn:name="PROP_intProjectCreationTimestamp" xil_pn:value="2018-03-12T08:17:29" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="PROP_intWbtProjectID" xil_pn:value="A745DC73C540110432FA7EE27F1D769D" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="PROP_intWorkingDirLocWRTProjDir" xil_pn:value="Same" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="PROP_intWorkingDirUsed" xil_pn:value="No" xil_pn:valueState="non-default"/>
+ </properties>
+
+ <bindings/>
+
+ <libraries/>
+
+ <autoManagedFiles>
+ <!-- The following files are identified by `include statements in verilog -->
+ <!-- source files and are automatically managed by Project Navigator. -->
+ <!-- -->
+ <!-- Do not hand-edit this section, as it will be overwritten when the -->
+ <!-- project is analyzed based on files automatically identified as -->
+ <!-- include files. -->
+ <file xil_pn:name="riscv.vh" xil_pn:type="FILE_VERILOG"/>
+ <file xil_pn:name="cpu.vh" xil_pn:type="FILE_VERILOG"/>
+ </autoManagedFiles>
+
+</project>
--- /dev/null
+---
+Language: Cpp
+BasedOnStyle: Google
+AccessModifierOffset: -4
+AlignAfterOpenBracket: true
+AlignConsecutiveAssignments: false
+AlignEscapedNewlinesLeft: true
+AlignOperands: true
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: true
+BinPackArguments: false
+BinPackParameters: false
+BreakBeforeBinaryOperators: NonAssignment
+BreakBeforeBraces: Allman
+BreakBeforeTernaryOperators: false
+BreakConstructorInitializersBeforeComma: false
+ColumnLimit: 100
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IndentCaseLabels: false
+IndentWidth: 4
+IndentWrappedFunctionNames: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 2
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 4
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: false
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Right
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: Never
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInCStyleCastParentheses: false
+SpacesInContainerLiterals: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 8
+UseTab: Never
+...
--- /dev/null
+emulated
+generate_hex_files.sh
+*.o
+ram.bin
+*.elf
+ram_?_byte?.hex
+
+
--- /dev/null
+# Copyright 2018 Jacob Lifshay
+#
+# 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.
+
+.PHONY: all clean
+
+LIBGCC := $(shell riscv32-unknown-elf-g++ -print-libgcc-file-name)
+LIBGCC_DIR := $(dir $(LIBGCC))
+
+all: ram0_byte0.hex ../output.bit emulated
+../output.bit: ram.elf ../main.bit
+ bash -c '. /opt/Xilinx/14.7/ISE_DS/settings64.sh; data2mem -bm ../cpu.bmm -bd ram.elf -bt ../main.bit -o b ../output.bit'
+ram0_byte0.hex: ram.bin generate_hex_files.sh Makefile
+ ./generate_hex_files.sh
+generate_hex_files.sh: make_block_memory.sh
+ ./make_block_memory.sh -s
+ram.bin: ram-stripped.elf Makefile
+ riscv32-unknown-elf-objcopy -O binary --pad-to 0x18000 ram.elf ram.bin
+OBJECTS := main.o \
+ start.o \
+ startup.o
+ram-stripped.elf: Makefile ram.elf
+ riscv32-unknown-elf-strip -o ram-stripped.elf ram.elf
+ram.elf: $(OBJECTS) Makefile ram.ld
+ riscv32-unknown-elf-ld -o ram.elf $(OBJECTS) -static -T ram.ld -L$(LIBGCC_DIR) -L/opt/riscv/riscv32-unknown-elf/lib -lgcc -lc
+startup.o: startup.S Makefile
+ riscv32-unknown-elf-g++ -c -o startup.o startup.S -march=rv32i -mabi=ilp32
+main.o: main.cpp Makefile
+start.o: start.cpp Makefile
+main-emulated.o: main.cpp Makefile
+ g++ -g -c -o main-emulated.o -std=c++14 -Wall main.cpp -DEMULATE_TARGET
+emulated: main-emulated.o Makefile
+ g++ -g -o emulated -std=c++14 -Wall main-emulated.o -static
+
+%.o: %.cpp
+ riscv32-unknown-elf-g++ -Os -c -o $@ $< -std=c++14 -Wall -march=rv32i -mabi=ilp32 -fno-exceptions
+
+clean:
+ rm -f ram*.hex ram.bin ram.elf ram-stripped.elf *.o emulated generate_hex_files.sh
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+#include <cstdint>
+#include <limits>
+
+inline void putchar(int ch)
+{
+#ifdef EMULATE_TARGET
+ switch(ch)
+ {
+ case 0xB2:
+ __builtin_printf("\u2593");
+ break;
+ case 0xB0:
+ __builtin_printf("\u2591");
+ break;
+ default:
+ __builtin_printf("%c", (char)ch);
+ }
+#else
+ *reinterpret_cast<volatile char *>(0x80000000) = ch;
+#endif
+}
+
+inline void write_hex_digit(int value)
+{
+ putchar("0123456789ABCDEF"[value]);
+}
+
+inline void write_hex_u8(std::uint8_t value)
+{
+ write_hex_digit(value >> 4);
+ write_hex_digit(value & 0xF);
+}
+
+inline void write_hex_u16(std::uint16_t value)
+{
+ write_hex_u8(value >> 8);
+ write_hex_u8(value & 0xFF);
+}
+
+inline void write_hex_u32(std::uint32_t value)
+{
+ write_hex_u16(value >> 16);
+ write_hex_u16(value & 0xFFFF);
+}
+
+inline std::uint32_t read_gpio()
+{
+#ifdef EMULATE_TARGET
+ return 0x0;
+#else
+ return *reinterpret_cast<volatile std::uint32_t *>(0x80000010);
+#endif
+}
+
+inline void write_gpio(std::uint32_t value)
+{
+#ifndef EMULATE_TARGET
+ *reinterpret_cast<volatile std::uint32_t *>(0x80000010) = value;
+#endif
+}
+
+constexpr std::uint32_t switch_2_mask = 0x200;
+constexpr std::uint32_t switch_3_mask = 0x400;
+
+inline void puts(const char *str)
+{
+ while(*str)
+ putchar(*str++);
+}
+
+constexpr std::size_t screen_x_size = 800 / 8;
+constexpr std::size_t screen_y_size = 600 / 8;
+
+template <typename T>
+struct get_double_length_type;
+
+template <>
+struct get_double_length_type<std::uint8_t>
+{
+ typedef std::uint16_t type;
+};
+
+template <>
+struct get_double_length_type<std::uint16_t>
+{
+ typedef std::uint32_t type;
+};
+
+template <>
+struct get_double_length_type<std::uint32_t>
+{
+ typedef std::uint64_t type;
+};
+
+template <>
+struct get_double_length_type<std::int8_t>
+{
+ typedef std::int16_t type;
+};
+
+template <>
+struct get_double_length_type<std::int16_t>
+{
+ typedef std::int32_t type;
+};
+
+template <>
+struct get_double_length_type<std::int32_t>
+{
+ typedef std::int64_t type;
+};
+
+template <typename T>
+constexpr T bidirectional_shift_left(T value, int amount) noexcept
+{
+ int max_shift = std::numeric_limits<T>::digits;
+ if(amount <= -max_shift)
+ return value < 0 ? -1 : 0;
+ if(amount < 0)
+ return value >> -amount;
+ return value << amount;
+}
+
+template <typename T>
+constexpr T bidirectional_shift_right(T value, int amount) noexcept
+{
+ return bidirectional_shift_left(value, -amount);
+}
+
+template <typename T = std::int32_t, std::size_t FractionalBits = 16>
+class Fixed
+{
+public:
+ typedef T underlying_type;
+ typedef typename get_double_length_type<T>::type double_length_type;
+ static constexpr std::size_t total_bits = std::numeric_limits<T>::digits;
+ static constexpr std::size_t fractional_bits = FractionalBits;
+ static constexpr std::size_t integer_bits = total_bits - fractional_bits;
+ static constexpr T fraction_mask = (static_cast<T>(1) << fractional_bits) - 1;
+ static constexpr T integer_mask = ~fraction_mask;
+ static_assert(total_bits >= fractional_bits, "");
+
+private:
+ underlying_type value;
+
+public:
+ constexpr Fixed() noexcept : value(0)
+ {
+ }
+ constexpr Fixed(signed char v) noexcept : value(static_cast<T>(v) << fractional_bits)
+ {
+ }
+ constexpr Fixed(short v) noexcept : value(static_cast<T>(v) << fractional_bits)
+ {
+ }
+ constexpr Fixed(int v) noexcept : value(static_cast<T>(v) << fractional_bits)
+ {
+ }
+ constexpr Fixed(long v) noexcept : value(static_cast<T>(v) << fractional_bits)
+ {
+ }
+ constexpr Fixed(long long v) noexcept : value(static_cast<T>(v) << fractional_bits)
+ {
+ }
+ constexpr Fixed(unsigned char v) noexcept : value(static_cast<T>(v) << fractional_bits)
+ {
+ }
+ constexpr Fixed(char v) noexcept : value(static_cast<T>(v) << fractional_bits)
+ {
+ }
+ constexpr Fixed(unsigned short v) noexcept : value(static_cast<T>(v) << fractional_bits)
+ {
+ }
+ constexpr Fixed(unsigned v) noexcept : value(static_cast<T>(v) << fractional_bits)
+ {
+ }
+ constexpr Fixed(unsigned long v) noexcept : value(static_cast<T>(v) << fractional_bits)
+ {
+ }
+ constexpr Fixed(unsigned long long v) noexcept : value(static_cast<T>(v) << fractional_bits)
+ {
+ }
+ constexpr Fixed(float v) noexcept
+ : value(static_cast<T>(static_cast<float>(1ULL << fractional_bits) * v))
+ {
+ }
+ constexpr Fixed(double v) noexcept
+ : value(static_cast<T>(static_cast<double>(1ULL << fractional_bits) * v))
+ {
+ }
+ constexpr explicit operator T() const noexcept
+ {
+ if(value < 0)
+ return (value + fraction_mask) >> fractional_bits;
+ return value >> fractional_bits;
+ }
+ constexpr explicit operator double() const noexcept
+ {
+ return value * (1.0 / (1ULL << fractional_bits));
+ }
+ static constexpr Fixed make(T underlying_value) noexcept
+ {
+ Fixed retval;
+ retval.value = underlying_value;
+ return retval;
+ }
+ constexpr Fixed operator+() const noexcept
+ {
+ return *this;
+ }
+ constexpr Fixed operator-() const noexcept
+ {
+ return make(-value);
+ }
+ friend constexpr Fixed operator+(Fixed a, Fixed b) noexcept
+ {
+ return make(a.value + b.value);
+ }
+ friend constexpr Fixed operator-(Fixed a, Fixed b) noexcept
+ {
+ return make(a.value - b.value);
+ }
+ friend constexpr Fixed operator*(Fixed a, Fixed b) noexcept
+ {
+ return make(static_cast<double_length_type>(a.value) * b.value >> fractional_bits);
+ }
+ friend constexpr Fixed operator/(Fixed a, Fixed b) noexcept
+ {
+ return make((static_cast<double_length_type>(a.value) << fractional_bits) / b.value);
+ }
+ constexpr Fixed &operator+=(Fixed rt) noexcept
+ {
+ return *this = *this + rt;
+ }
+ constexpr Fixed &operator-=(Fixed rt) noexcept
+ {
+ return *this = *this - rt;
+ }
+ constexpr Fixed &operator*=(Fixed rt) noexcept
+ {
+ return *this = *this * rt;
+ }
+ constexpr Fixed &operator/=(Fixed rt) noexcept
+ {
+ return *this = *this / rt;
+ }
+ constexpr T underlying_value() const noexcept
+ {
+ return value;
+ }
+ friend constexpr bool operator==(Fixed a, Fixed b) noexcept
+ {
+ return a.value == b.value;
+ }
+ friend constexpr bool operator!=(Fixed a, Fixed b) noexcept
+ {
+ return a.value != b.value;
+ }
+ friend constexpr bool operator<=(Fixed a, Fixed b) noexcept
+ {
+ return a.value <= b.value;
+ }
+ friend constexpr bool operator>=(Fixed a, Fixed b) noexcept
+ {
+ return a.value >= b.value;
+ }
+ friend constexpr bool operator<(Fixed a, Fixed b) noexcept
+ {
+ return a.value < b.value;
+ }
+ friend constexpr bool operator>(Fixed a, Fixed b) noexcept
+ {
+ return a.value > b.value;
+ }
+ friend constexpr Fixed floor(Fixed v) noexcept
+ {
+ v.value &= integer_mask;
+ return v;
+ }
+ friend constexpr Fixed fracf(Fixed v) noexcept
+ {
+ v.value &= fraction_mask;
+ return v;
+ }
+ friend constexpr Fixed ceil(Fixed v) noexcept
+ {
+ v.value += fraction_mask;
+ return floor(v);
+ }
+ friend constexpr Fixed round(Fixed v) noexcept
+ {
+ constexpr Fixed one_half = 0.5;
+ v += one_half;
+ return floor(v);
+ }
+ friend constexpr T floori(Fixed v) noexcept
+ {
+ return v.value >> fractional_bits;
+ }
+ friend constexpr T ceili(Fixed v) noexcept
+ {
+ v.value += fraction_mask;
+ return floori(v);
+ }
+ friend constexpr T roundi(Fixed v) noexcept
+ {
+ constexpr Fixed one_half = 0.5;
+ v += one_half;
+ return floori(v);
+ }
+ friend constexpr Fixed abs(Fixed v) noexcept
+ {
+ if(v.value < 0)
+ return -v;
+ return v;
+ }
+ friend constexpr Fixed sqrt(Fixed v) noexcept
+ {
+ if(v <= 0)
+ return 0;
+ Fixed guess = 0;
+ double_length_type guess_squared = 0;
+ for(int bit_index = (integer_bits + 1) / 2; bit_index >= -static_cast<int>(fractional_bits);
+ bit_index--)
+ {
+ Fixed new_guess = guess + make(static_cast<T>(1) << (bit_index + fractional_bits));
+ double_length_type new_guess_squared = guess_squared;
+ new_guess_squared += bidirectional_shift_left(
+ static_cast<double_length_type>(guess.value), bit_index + 1);
+ new_guess_squared += bidirectional_shift_left(
+ static_cast<double_length_type>(Fixed(1).value), 2 * bit_index);
+ if(new_guess_squared < v.value)
+ {
+ guess = new_guess;
+ guess_squared = new_guess_squared;
+ }
+ else if(new_guess_squared == v.value)
+ return new_guess;
+ }
+ return guess;
+ }
+};
+
+enum class Block : char
+{
+ Empty = ' ',
+ Wall = '|',
+ End = 'X'
+};
+
+constexpr double constexpr_sin2pi(double x) noexcept
+{
+ x -= static_cast<long long>(x);
+ if(x < 0)
+ x += 1;
+ if(x == 0)
+ return 0;
+ if(x == 0.25)
+ return 1;
+ if(x == 0.5)
+ return 0;
+ if(x == 0.75)
+ return -1;
+ double x2 = x * x;
+ const double coefficients[] = {
+ 1.5873670538243229332222957023504872028033458258785e-8,
+ -3.2649283479971170585768247133750680886632233028762e-7,
+ 5.8056524029499061679627827975252772363553363262495e-6,
+ -8.8235335992430051344844841671401871742374913922057e-5,
+ 1.1309237482517961877702180414488525515732161905954e-3,
+ -1.2031585942120627233202567845286556653885737182738e-2,
+ 1.0422916220813984117271044898760411097029995316417e-1,
+ -7.1812230177850051223174027860686238053986168884284e-1,
+ 3.8199525848482821277337920673404661254406128731422,
+ -1.5094642576822990391826616232531520514481435107371e1,
+ 4.205869394489765314498681114813355254161277992845e1,
+ -7.6705859753061385841630641093893125889966539055122e1,
+ 8.1605249276075054203397682678249495061413521767487e1,
+ -4.1341702240399760233968420089468526936300384754514e1,
+ 6.2831853071795864769252867665590057683943387987502,
+ };
+ double v = 0;
+ for(double coeff : coefficients)
+ v = v * x2 + coeff;
+ return x * v;
+}
+
+constexpr double constexpr_cos2pi(double x) noexcept
+{
+ x -= static_cast<long long>(x);
+ x += 0.25;
+ return constexpr_sin2pi(x);
+}
+
+template <std::size_t N = 65>
+struct SinCosList
+{
+ static_assert(N > 1, "");
+ constexpr std::size_t size() const noexcept
+ {
+ return N;
+ }
+ Fixed<> sin_table[N];
+ constexpr SinCosList() noexcept : sin_table{}
+ {
+ for(std::size_t i = 0; i < N; i++)
+ {
+ double rotations = i / (4.0 * (N - 1));
+ sin_table[i] = constexpr_sin2pi(rotations);
+ }
+ }
+ constexpr void get(Fixed<> &sin_out, Fixed<> &cos_out, Fixed<> rotations) const noexcept
+ {
+ rotations = fracf(rotations) * 4;
+ int quadrent = floori(rotations);
+ rotations = (N - 1) * fracf(rotations);
+ auto int_part = floori(rotations);
+ auto fraction = fracf(rotations);
+ auto sin_value =
+ sin_table[int_part] + fraction * (sin_table[int_part + 1] - sin_table[int_part]);
+ auto cos_value =
+ sin_table[N - 1 - int_part]
+ + fraction * (sin_table[N - 1 - int_part - 1] - sin_table[N - 1 - int_part]);
+ switch(quadrent)
+ {
+ case 1:
+ sin_out = cos_value;
+ cos_out = -sin_value;
+ break;
+ case 2:
+ sin_out = -sin_value;
+ cos_out = -cos_value;
+ break;
+ case 3:
+ sin_out = -cos_value;
+ cos_out = sin_value;
+ break;
+ default:
+ sin_out = sin_value;
+ cos_out = cos_value;
+ break;
+ }
+ }
+ constexpr Fixed<> get_sin(Fixed<> rotations) const noexcept
+ {
+ Fixed<> sin, cos;
+ get(sin, cos, rotations);
+ return sin;
+ }
+ constexpr Fixed<> get_cos(Fixed<> rotations) const noexcept
+ {
+ Fixed<> sin, cos;
+ get(sin, cos, rotations);
+ return cos;
+ }
+};
+
+constexpr auto sin_cos_list = SinCosList<>();
+
+constexpr void rotate(Fixed<> &x, Fixed<> &y, Fixed<> rotations)
+{
+ Fixed<> sin, cos;
+ sin_cos_list.get(sin, cos, rotations);
+ auto new_x = x * cos - y * sin;
+ auto new_y = x * sin + y * cos;
+ x = new_x;
+ y = new_y;
+}
+
+inline void write_fixed(Fixed<> v)
+{
+ write_hex_u32(floori(v));
+ putchar('.');
+ write_hex_u16(floori(fracf(v) * 0x10000));
+}
+
+template <typename T>
+struct Vec2D
+{
+ typedef T element_type;
+ T x, y;
+ constexpr Vec2D() noexcept : x(), y()
+ {
+ }
+ constexpr explicit Vec2D(T v) noexcept : x(v), y(v)
+ {
+ }
+ constexpr Vec2D(T x, T y) noexcept : x(x), y(y)
+ {
+ }
+ friend constexpr Vec2D operator+(Vec2D a, Vec2D b) noexcept
+ {
+ return Vec2D(a.x + b.x, a.y + b.y);
+ }
+ friend constexpr Vec2D operator-(Vec2D a, Vec2D b) noexcept
+ {
+ return Vec2D(a.x - b.x, a.y - b.y);
+ }
+ friend constexpr Vec2D operator*(T a, Vec2D b) noexcept
+ {
+ return Vec2D(a * b.x, a * b.y);
+ }
+ friend constexpr Vec2D operator*(Vec2D a, T b) noexcept
+ {
+ return Vec2D(a.x * b, a.y * b);
+ }
+ friend constexpr Vec2D operator/(Vec2D a, T b) noexcept
+ {
+ return Vec2D(a.x / b, a.y / b);
+ }
+ constexpr Vec2D &operator+=(Vec2D rt) noexcept
+ {
+ return *this = *this + rt;
+ }
+ constexpr Vec2D &operator-=(Vec2D rt) noexcept
+ {
+ return *this = *this - rt;
+ }
+ constexpr Vec2D &operator*=(T rt) noexcept
+ {
+ return *this = *this * rt;
+ }
+ constexpr Vec2D &operator/=(T rt) noexcept
+ {
+ return *this = *this / rt;
+ }
+};
+
+constexpr Vec2D<Fixed<>> rotate(Vec2D<Fixed<>> v, Fixed<> rotations) noexcept
+{
+ rotate(v.x, v.y, rotations);
+ return v;
+}
+
+constexpr void init_ray_cast_dimension(Fixed<> ray_direction,
+ Fixed<> ray_start_position,
+ std::int32_t current_position,
+ Fixed<> &next_t,
+ Fixed<> &step_t,
+ std::int32_t &delta_position)
+{
+ if(ray_direction == 0)
+ return;
+ auto inverse_direction = 1 / ray_direction;
+ step_t = abs(inverse_direction);
+ std::int32_t target_position{};
+ if(ray_direction < 0)
+ {
+ target_position = ceili(ray_start_position) - 1;
+ delta_position = -1;
+ }
+ else
+ {
+ target_position = floori(ray_start_position) + 1;
+ delta_position = 1;
+ }
+ next_t = (target_position - ray_start_position) * inverse_direction;
+}
+
+struct RayCaster
+{
+ Vec2D<Fixed<>> ray_start_position;
+ Vec2D<Fixed<>> ray_direction;
+ Vec2D<std::int32_t> current_position;
+ Fixed<> current_t;
+ Vec2D<Fixed<>> next_t;
+ Vec2D<Fixed<>> step_t;
+ Vec2D<std::int32_t> delta_position;
+ int last_hit_dimension = -1;
+ constexpr RayCaster(Vec2D<Fixed<>> ray_start_position, Vec2D<Fixed<>> ray_direction) noexcept
+ : ray_start_position(ray_start_position),
+ ray_direction(ray_direction),
+ current_position(floori(ray_start_position.x), floori(ray_start_position.y)),
+ current_t(Fixed<>::make(1)),
+ next_t(0),
+ step_t(0),
+ delta_position(0)
+ {
+ init_ray_cast_dimension(ray_direction.x,
+ ray_start_position.x,
+ current_position.x,
+ next_t.x,
+ step_t.x,
+ delta_position.x);
+ init_ray_cast_dimension(ray_direction.y,
+ ray_start_position.y,
+ current_position.y,
+ next_t.y,
+ step_t.y,
+ delta_position.y);
+ }
+ constexpr void step() noexcept
+ {
+ if(ray_direction.x != 0 && (ray_direction.y == 0 || next_t.x < next_t.y))
+ {
+ current_t = next_t.x;
+ next_t.x += step_t.x;
+ current_position.x += delta_position.x;
+ last_hit_dimension = 0;
+ }
+ else if(ray_direction.y != 0)
+ {
+ current_t = next_t.y;
+ next_t.y += step_t.y;
+ current_position.y += delta_position.y;
+ last_hit_dimension = 1;
+ }
+ }
+};
+
+int main()
+{
+ static std::uint8_t start_col[screen_x_size] = {}, end_col[screen_x_size] = {};
+ static char col_color[screen_x_size] = {};
+ constexpr std::size_t world_x_size = 16, world_z_size = 16;
+ static const char world[world_x_size][world_z_size] = {
+ // clang-format off
+ {'|', '|', '|', '|', '|', '|', '|', '|', '|', '|', '|', '|', '|', '|', 'X', 'X'},
+ {'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', ' ', 'X'},
+ {'|', ' ', '|', '|', '|', '|', '|', '|', '|', ' ', ' ', '|', ' ', ' ', ' ', 'X'},
+ {'|', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', ' ', '|', ' ', '|', 'X', 'X'},
+ {'|', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', ' ', '|', ' ', '|', '|', '|'},
+ {'|', ' ', '|', ' ', ' ', '|', ' ', ' ', '|', ' ', ' ', '|', ' ', ' ', ' ', '|'},
+ {'|', ' ', '|', ' ', ' ', '|', ' ', ' ', '|', ' ', ' ', '|', ' ', ' ', ' ', '|'},
+ {'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', '|', '|', ' ', '|'},
+ {'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', ' ', ' ', '|'},
+ {'|', ' ', '|', '|', '|', '|', '|', '|', '|', ' ', ' ', '|', ' ', ' ', ' ', '|'},
+ {'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|'},
+ {'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|'},
+ {'|', ' ', '|', '|', '|', '|', '|', '|', '|', ' ', ' ', '|', ' ', ' ', ' ', '|'},
+ {'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|'},
+ {'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|'},
+ {'|', '|', '|', '|', '|', '|', '|', '|', '|', '|', '|', '|', '|', '|', '|', '|'},
+ // clang-format on
+ };
+ Vec2D<Fixed<>> view_position(1.5, 1.5);
+ Fixed<> view_angle(0);
+ std::uint32_t flash_counter = 0;
+ constexpr std::uint32_t flash_period = 10;
+ while(true)
+ {
+ flash_counter++;
+ if(flash_counter >= flash_period)
+ flash_counter = 0;
+ if(read_gpio() & switch_2_mask)
+ {
+ view_angle += 0.01;
+ view_angle = fracf(view_angle);
+ }
+ if(read_gpio() & switch_3_mask)
+ {
+ Vec2D<Fixed<>> forward(0, 0.05);
+ forward = rotate(forward, view_angle);
+ auto new_view_position = view_position + forward;
+ Vec2D<std::int32_t> new_block_position(floori(new_view_position.x),
+ floori(new_view_position.y));
+#if 1
+ auto block = world[new_block_position.x][new_block_position.y];
+ if(block == ' ')
+ view_position = new_view_position;
+#else
+ Fixed<> closest_distance(100);
+ for(int dx = -1; dx <= 1; dx++)
+ {
+ for(int dy = -1; dy <= 1; dy++)
+ {
+ auto block_position = new_block_position;
+ block_position.x += dx;
+ block_position.y += dy;
+ auto block = world[block_position.x][block_position.y];
+ if(block == ' ')
+ continue;
+ auto closest_position = new_view_position;
+ if(closest_position.x < block_position.x)
+ closest_position.x = block_position.x;
+ else if(closest_position.x > block_position.x + 1)
+ closest_position.x = block_position.x + 1;
+ if(closest_position.y < block_position.y)
+ closest_position.y = block_position.y;
+ else if(closest_position.y > block_position.y + 1)
+ closest_position.y = block_position.y + 1;
+ auto current_distance_x = abs(closest_position.x - block_position.x);
+ auto current_distance_y = abs(closest_position.y - block_position.y);
+ auto current_distance = current_distance_x;
+ if(current_distance < current_distance_y)
+ current_distance = current_distance_y;
+ if(current_distance < closest_distance)
+ closest_distance = current_distance;
+ }
+ }
+ if(closest_distance >= 0.1)
+ view_position = new_view_position;
+#endif
+ }
+ for(std::size_t x = 0; x < screen_x_size; x++)
+ {
+ Vec2D<Fixed<>> ray_direction(
+ (Fixed<>(x) + (0.5 - screen_x_size / 2.0)) * (2.0 / screen_x_size), 1);
+ ray_direction = rotate(ray_direction, view_angle);
+ RayCaster ray_caster(view_position, ray_direction);
+ auto hit_block = world[ray_caster.current_position.x][ray_caster.current_position.y];
+ while(hit_block == ' ')
+ {
+ ray_caster.step();
+ hit_block = world[ray_caster.current_position.x][ray_caster.current_position.y];
+ }
+ constexpr Fixed<> max_height = 10;
+ Fixed<> height = ray_caster.current_t != Fixed<>::make(1) ?
+ 1 / ray_caster.current_t :
+ max_height;
+ if(height > max_height)
+ height = max_height;
+ height *= screen_x_size / 2.0;
+ auto iheight = roundi(height);
+ if(iheight > static_cast<int>(screen_y_size))
+ iheight = screen_y_size;
+ else if(iheight < 0)
+ iheight = 0;
+ start_col[x] = screen_y_size / 2 - iheight / 2;
+ end_col[x] = screen_y_size / 2 + (iheight + 1) / 2;
+ col_color[x] = 0xB0;
+ if(hit_block == 'X' && flash_counter >= flash_period / 2)
+ {
+ col_color[x] = '#';
+ if(ray_caster.last_hit_dimension == 0)
+ col_color[x] = 'X';
+ }
+ else if(ray_caster.last_hit_dimension == 0)
+ {
+ col_color[x] = 0xB1;
+ }
+ }
+ puts("\x1B[H");
+ for(std::size_t y = 0; y < screen_y_size; y++)
+ {
+ for(std::size_t x = 0,
+ x_end = (y == screen_y_size - 1 ? screen_x_size - 1 : screen_x_size);
+ x < x_end;
+ x++)
+ {
+ if(y >= end_col[x])
+ putchar(0xB2);
+ else if(y >= start_col[x])
+ putchar(col_color[x]);
+ else
+ putchar(0x20);
+ }
+ }
+ }
+}
--- /dev/null
+#!/bin/bash
+# Copyright 2018 Jacob Lifshay
+#
+# 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.
+
+# 32KiB
+memory_size=$((32<<10))
+# 16kbit
+block_size_log_2=11
+
+output_file=""
+
+function open_output_file()
+{
+ output_file="$1"
+ exec >"$1"
+}
+
+function error()
+{
+ echo "error:" "$@" >&2
+ if [[ "" != "$output_file" ]]; then
+ rm "$output_file"
+ fi
+ exit 1
+}
+
+chunk_size_log_2=$((block_size_log_2+2))
+chunk_size=$((1<<chunk_size_log_2))
+chunk_count=$((memory_size / chunk_size))
+((memory_size % chunk_size == 0)) || error "memory_size must be a multiple of chunk_size"
+
+if [[ "$1" == "-v" ]]; then
+ open_output_file block_memory.v
+ cat <<EOF
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+\`timescale 1ns / 1ps
+
+module block_memory(
+ input clk,
+ input [31:0] a_ram_address,
+ input [3:0] a_write_enable,
+ input [31:0] a_write_input,
+ output reg [31:0] a_read_output,
+ input [31:0] b_ram_address,
+ output reg [31:0] b_read_output
+ );
+EOF
+
+ for((i = 0; i < chunk_count; i++)); do
+ cat <<EOF
+
+ wire a_enable_${i} = a_ram_address[31:${block_size_log_2}] == ${i};
+ wire b_enable_${i} = b_ram_address[31:${block_size_log_2}] == ${i};
+ wire [3:0] a_write_enable_${i} = {4{a_enable_${i}}} & a_write_enable;
+ wire [31:0] a_read_output_${i};
+ wire [31:0] b_read_output_${i};
+EOF
+ for byte in {0..3}; do
+ cat <<EOF
+ block_memory_16kbit #(
+ .initial_file("software/ram_${i}_byte${byte}.hex")
+ ) ram_${i}_byte${byte}(
+ .clk(clk),
+ .port_a_address(a_ram_address[$((block_size_log_2 - 1)):0]),
+ .port_a_write_enable(a_write_enable_${i}[${byte}]),
+ .port_a_write_input(a_write_input[$((byte * 8 + 7)):$((byte * 8))]),
+ .port_a_read_output(a_read_output_${i}[$((byte * 8 + 7)):$((byte * 8))]),
+ .port_b_address(b_ram_address[$((block_size_log_2 - 1)):0]),
+ .port_b_read_output(b_read_output_${i}[$((byte * 8 + 7)):$((byte * 8))])
+ );
+
+EOF
+ done
+ done
+
+ cat <<EOF
+
+ always @* begin
+ case(a_ram_address[31:${block_size_log_2}])
+EOF
+
+ for((i = 0; i < chunk_count; i++)); do
+ cat <<EOF
+ ${i}: a_read_output = a_read_output_${i};
+EOF
+ done
+
+ cat <<EOF
+ default: a_read_output = 32'hXXXXXXXX;
+ endcase
+ end
+
+ always @* begin
+ case(b_ram_address[31:${block_size_log_2}])
+EOF
+
+ for((i = 0; i < chunk_count; i++)); do
+ cat <<EOF
+ ${i}: b_read_output = b_read_output_${i};
+EOF
+ done
+
+ cat <<EOF
+ default: b_read_output = 32'hXXXXXXXX;
+ endcase
+ end
+endmodule
+EOF
+ exit 0
+elif [[ "$1" == "-s" ]]; then
+ open_output_file generate_hex_files.sh
+ chmod +x generate_hex_files.sh
+ cat <<EOF
+#!/bin/bash
+# Copyright 2018 Jacob Lifshay
+#
+# 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.
+
+mapfile -t words < <(hexdump -v -e '/4 "%08X\n"' < ram.bin)
+chunk_size=${chunk_size}
+chunk_count=${chunk_count}
+EOF
+ cat <<'EOF'
+if (( chunk_size * chunk_count != 4 * ${#words[@]} )); then
+ echo "ram.bin is the wrong size: expected $((chunk_size * chunk_count / 4)) words, got ${#words[@]}" >&2
+ exit 1
+fi
+word_index=0
+for((chunk=0;chunk<chunk_count;chunk++)); do
+ exec 3>"ram_${chunk}_byte0.hex" 4>"ram_${chunk}_byte1.hex" 5>"ram_${chunk}_byte2.hex" 6>"ram_${chunk}_byte3.hex"
+ for((i=0;i<chunk_size;i+=4)); do
+ word="${words[word_index++]}"
+ echo "${word:6:2}" >&3
+ echo "${word:4:2}" >&4
+ echo "${word:2:2}" >&5
+ echo "${word:0:2}" >&6
+ done
+done
+exit 0
+EOF
+else
+ error $'unknown option\nusage: '"$0"$' [-v|-s]\n-v\tgenerate block_memory.v\n-s\tgenerate generate_hex_files.sh'
+fi
+
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+SECTIONS
+{
+ . = 0x10000;
+ .ram : {
+ *(.startup)
+ *(.text*)
+ __global_pointer$ = . + 0x800;
+ *(.sdata*)
+ *(.sbss*)
+ *(.data*)
+ *(.rodata*)
+ *(.bss*)
+ }
+ /DISCARD/ : {
+ *(.comment)
+ }
+}
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+#include <cstdint>
+
+int main(int argc, char **argv);
+
+extern "C" void _start() noexcept
+{
+ static char arg0[] = "";
+ static char *argv[2] = {arg0, nullptr};
+ main(1, argv);
+ while(true)
+ {
+ asm("wfi");
+ }
+}
+
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+.global _start
+.section .startup
+.option push
+.option norelax
+.reset:
+la gp, __global_pointer$
+li sp, 0x18000
+.option pop
+j _start
+.balign 0x40
+.trap:
+j .trap
--- /dev/null
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 100ps
+
+module vga(
+ input clk,
+ output [7:0] vga_r,
+ output [7:0] vga_g,
+ output [7:0] vga_b,
+ output vga_hsync,
+ output vga_vsync,
+ output vga_blank,
+ output vga_pixel_clock,
+ input tty_write,
+ input [7:0] tty_data,
+ output tty_busy
+ );
+
+ wire pixel_clock;
+
+ vga_clock_generator clock_generator(clk, pixel_clock);
+
+ wire location_generator_hsync;
+ wire location_generator_vsync;
+ wire location_generator_blank;
+ wire [15:0] location_generator_x;
+ wire [15:0] location_generator_y;
+ wire location_generator_xy_in_active;
+
+ vga_location_generator location_generator(pixel_clock,
+ location_generator_hsync,
+ location_generator_vsync,
+ location_generator_blank,
+ location_generator_x,
+ location_generator_y,
+ location_generator_xy_in_active);
+
+ wire [7:0] text_buffer_screen_char;
+ reg text_buffer_hsync;
+ reg text_buffer_vsync;
+ reg text_buffer_blank;
+ reg [15:0] text_buffer_x;
+ reg [15:0] text_buffer_y;
+ reg text_buffer_xy_in_active;
+
+ initial text_buffer_hsync = 0;
+ initial text_buffer_vsync = 0;
+ initial text_buffer_blank = 0;
+ initial text_buffer_x = 0;
+ initial text_buffer_y = 0;
+ initial text_buffer_xy_in_active = 0;
+
+ always @(posedge pixel_clock) text_buffer_hsync <= location_generator_hsync;
+ always @(posedge pixel_clock) text_buffer_vsync <= location_generator_vsync;
+ always @(posedge pixel_clock) text_buffer_blank <= location_generator_blank;
+ always @(posedge pixel_clock) text_buffer_x <= location_generator_x;
+ always @(posedge pixel_clock) text_buffer_y <= location_generator_y;
+ always @(posedge pixel_clock) text_buffer_xy_in_active <= location_generator_xy_in_active;
+
+ vga_text_buffer text_buffer(pixel_clock,
+ location_generator_x,
+ location_generator_y,
+ location_generator_xy_in_active,
+ text_buffer_screen_char,
+ clk,
+ tty_write,
+ tty_data,
+ tty_busy);
+
+ wire [7:0] font_generator_r;
+ wire [7:0] font_generator_g;
+ wire [7:0] font_generator_b;
+
+ vga_font_generator font_generator(
+ pixel_clock,
+ text_buffer_x,
+ text_buffer_y,
+ text_buffer_xy_in_active,
+ text_buffer_screen_char,
+ font_generator_r,
+ font_generator_g,
+ font_generator_b);
+
+ reg font_generator_hsync;
+ reg font_generator_vsync;
+ reg font_generator_blank;
+
+ initial font_generator_hsync = 0;
+ initial font_generator_vsync = 0;
+ initial font_generator_blank = 0;
+
+ always @(posedge pixel_clock) font_generator_hsync <= text_buffer_hsync;
+ always @(posedge pixel_clock) font_generator_vsync <= text_buffer_vsync;
+ always @(posedge pixel_clock) font_generator_blank <= text_buffer_blank;
+
+ assign vga_pixel_clock = ~pixel_clock;
+
+ reg output_hsync;
+ reg output_vsync;
+ reg output_blank;
+ reg [7:0] output_r;
+ reg [7:0] output_g;
+ reg [7:0] output_b;
+
+ initial output_hsync = 0;
+ initial output_vsync = 0;
+ initial output_blank = 0;
+ initial output_r = 0;
+ initial output_g = 0;
+ initial output_b = 0;
+
+ always @(posedge pixel_clock) output_hsync = font_generator_hsync;
+ always @(posedge pixel_clock) output_vsync = font_generator_vsync;
+ always @(posedge pixel_clock) output_blank = font_generator_blank;
+ always @(posedge pixel_clock) output_r = font_generator_r;
+ always @(posedge pixel_clock) output_g = font_generator_g;
+ always @(posedge pixel_clock) output_b = font_generator_b;
+
+ assign vga_r = output_r;
+ assign vga_g = output_g;
+ assign vga_b = output_b;
+
+ reg final_hsync;
+ reg final_vsync;
+ reg final_blank;
+
+ initial final_hsync = 0;
+ initial final_vsync = 0;
+ initial final_blank = 0;
+
+ always @(posedge pixel_clock) final_hsync = output_hsync;
+ always @(posedge pixel_clock) final_vsync = output_vsync;
+ always @(posedge pixel_clock) final_blank = font_generator_blank;
+
+ assign vga_hsync = final_hsync;
+ assign vga_vsync = final_vsync;
+ assign vga_blank = font_generator_blank;
+endmodule
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 100ps
+
+module vga_clock_generator(
+ input clk,
+ output pixel_clock
+ );
+
+ assign pixel_clock = clk;
+endmodule
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 100ps
+
+module vga_font_generator(
+ input pixel_clock,
+ input [15:0] screen_x,
+ input [15:0] screen_y,
+ input screen_valid,
+ input [7:0] screen_char,
+ output [7:0] vga_r,
+ output [7:0] vga_g,
+ output [7:0] vga_b
+ );
+
+ parameter font_x_size = 8;
+ parameter font_y_size = 8;
+
+ // ram_style = "block"
+ reg [font_x_size - 1 : 0] font8x8[0 : 256 * font_y_size - 1];
+
+ initial $readmemh("font8x8.hex", font8x8);
+
+ wire [2:0] sub_char_x = screen_x[2:0];
+ wire [2:0] sub_char_y = screen_y[2:0];
+ wire [15:0] font_address = {screen_char, sub_char_y};
+ reg [7:0] font_line;
+ reg [2:0] output_sub_char_x;
+
+ initial font_line = 0;
+ initial output_sub_char_x = 0;
+
+ always @(posedge pixel_clock) begin
+ font_line <= font8x8[font_address];
+ output_sub_char_x <= sub_char_x;
+ end
+
+ wire pixel_active = ((font_line >> output_sub_char_x) & 1) == 1;
+ assign vga_r = pixel_active ? 255 : 0;
+ assign vga_g = pixel_active ? 255 : 0;
+ assign vga_b = pixel_active ? 255 : 0;
+
+endmodule
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 100ps
+
+module vga_location_generator(
+ input pixel_clock,
+ output reg hsync,
+ output reg vsync,
+ output reg blank,
+ output reg [15:0] x,
+ output reg [15:0] y,
+ output reg xy_in_active
+ );
+
+ parameter x_front_porch = 56;
+ parameter x_active = 800;
+ parameter x_back_porch = 64;
+ parameter x_sync = 120;
+ parameter y_front_porch = 37;
+ parameter y_active = 600;
+ parameter y_back_porch = 23;
+ parameter y_sync = 6;
+
+ wire x_at_end = (x == x_active + x_back_porch + x_sync + x_front_porch);
+ wire y_at_end = (y == y_active + y_back_porch + y_sync + y_front_porch);
+ wire [15:0] next_x = x_at_end ? 0 : x + 1;
+ wire [15:0] next_y = x_at_end ? (y_at_end ? 0 : y + 1) : y;
+ wire next_xy_in_active = (next_x < x_active) & (next_y < y_active);
+
+ initial begin
+ hsync = 0;
+ vsync = 0;
+ blank = 0;
+ x = 0;
+ y = 0;
+ end
+
+ always @(posedge pixel_clock) begin
+ x <= next_x;
+ y <= next_y;
+ blank <= next_xy_in_active;
+ hsync <= ((x >= x_active + x_back_porch) & (x < x_active + x_back_porch + x_sync));
+ vsync <= ((y >= y_active + y_back_porch) & (y < y_active + y_back_porch + y_sync));
+ xy_in_active <= next_xy_in_active;
+ end
+endmodule
--- /dev/null
+/*
+ * Copyright 2018 Jacob Lifshay
+ *
+ * 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.
+ *
+ */
+`timescale 1ns / 100ps
+
+module vga_text_buffer(
+ input pixel_clock,
+ input [15:0] screen_x,
+ input [15:0] screen_y,
+ input screen_valid,
+ output reg [7:0] screen_char,
+ input clk,
+ input tty_write,
+ input [7:0] tty_data,
+ output reg tty_busy
+ );
+
+ parameter font_x_size = 8;
+ parameter font_y_size = 8;
+ parameter screen_x_size = 800;
+ parameter screen_y_size = 600;
+ parameter text_x_size = screen_x_size / font_x_size;
+ parameter text_y_size = screen_y_size / font_y_size;
+ parameter ram_x_size = 128;
+ parameter ram_y_size = 128;
+
+ // ram_style = "block"
+ reg [7:0] text_ram[ram_x_size * ram_y_size - 1 : 0];
+
+ initial $readmemh("text_initial.hex", text_ram);
+
+ initial tty_busy = 1;
+
+ initial screen_char = 0;
+
+ reg [11:0] scroll_amount;
+
+ initial scroll_amount = 0;
+
+ always @(posedge pixel_clock) begin
+ screen_char <= screen_valid ? text_ram[ram_x_size * ((screen_y / font_y_size) + scroll_amount) + (screen_x / font_x_size)] : 0;
+ end
+
+ reg [11:0] cursor_x;
+ reg [11:0] cursor_y;
+
+ initial cursor_x = 0;
+ initial cursor_y = 0;
+
+ reg [2:0] state;
+
+ initial state = 0;
+
+ wire [11:0] cursor_x_after_tab_unwrapped = ((cursor_x >> 3) + 1) << 3;
+ wire [11:0] cursor_x_after_tab = (cursor_x_after_tab_unwrapped == text_x_size ? 0 : cursor_x_after_tab_unwrapped);
+
+ reg [15:0] text_ram_write_address;
+ reg text_ram_write_enable;
+ reg [7:0] text_ram_write_data;
+
+ always @(posedge clk) begin
+ if(text_ram_write_enable)
+ text_ram[text_ram_write_address] <= text_ram_write_data;
+ end
+
+ parameter space_char = 'h20;
+ parameter escape_char = 'h1B;
+ parameter left_bracket_char = 'h5B;
+ parameter capital_H_char = 'h48;
+
+ always @(posedge clk) begin
+ text_ram_write_enable = 0;
+ case(state)
+ 0: begin
+ cursor_x <= 0;
+ cursor_y <= 0;
+ tty_busy <= 1;
+ state <= 1;
+ scroll_amount <= 0;
+ end
+ 1: begin
+ if(cursor_x != ram_x_size - 1) begin
+ tty_busy <= 1;
+ text_ram_write_enable = 1;
+ text_ram_write_address = ram_x_size * (cursor_y + scroll_amount) + cursor_x;
+ text_ram_write_data = space_char;
+ cursor_x <= cursor_x + 1;
+ end
+ else if(cursor_y != ram_y_size - 1) begin
+ tty_busy <= 1;
+ text_ram_write_enable = 1;
+ text_ram_write_address = ram_x_size * (cursor_y + scroll_amount) + cursor_x;
+ text_ram_write_data = space_char;
+ cursor_x <= 0;
+ cursor_y <= cursor_y + 1;
+ end
+ else begin
+ text_ram_write_enable = 1;
+ text_ram_write_address = ram_x_size * (cursor_y + scroll_amount) + cursor_x;
+ text_ram_write_data = space_char;
+ tty_busy <= 0;
+ state <= 2;
+ cursor_x <= 0;
+ cursor_y <= 0;
+ end
+ end
+ 2: begin
+ if(tty_write) begin
+ case (tty_data)
+ 'h0A: begin
+ if(cursor_y != text_y_size - 1) begin
+ cursor_x <= 0;
+ cursor_y <= cursor_y + 1;
+ tty_busy <= 0;
+ end
+ else begin
+ cursor_x <= 0;
+ tty_busy <= 1;
+ state <= 3;
+ scroll_amount <= scroll_amount + 1;
+ end
+ end
+ 'h1B: begin
+ tty_busy <= 0;
+ state <= 4;
+ end
+ 'h0D: begin
+ cursor_x <= 0;
+ tty_busy <= 0;
+ end
+ 'h09: begin
+ cursor_x <= cursor_x_after_tab;
+ tty_busy <= 0;
+ end
+ default: begin
+ text_ram_write_enable = 1;
+ text_ram_write_address = ram_x_size * (cursor_y + scroll_amount) + cursor_x;
+ text_ram_write_data = tty_data;
+ if(cursor_x != text_x_size - 1) begin
+ cursor_x <= cursor_x + 1;
+ tty_busy <= 0;
+ end
+ else if(cursor_y != text_y_size - 1) begin
+ cursor_x <= 0;
+ cursor_y <= cursor_y + 1;
+ tty_busy <= 0;
+ end
+ else begin
+ cursor_x <= 0;
+ cursor_y <= text_y_size - 1;
+ tty_busy <= 1;
+ state <= 3;
+ scroll_amount <= scroll_amount + 1;
+ end
+ end
+ endcase
+ end
+ else begin
+ tty_busy <= 0;
+ end
+ end
+ 3: begin
+ if(cursor_x != ram_x_size - 1) begin
+ tty_busy <= 1;
+ text_ram_write_enable = 1;
+ text_ram_write_address = ram_x_size * (cursor_y + scroll_amount) + cursor_x;
+ text_ram_write_data = space_char;
+ cursor_x <= cursor_x + 1;
+ end
+ else begin
+ text_ram_write_enable = 1;
+ text_ram_write_address = ram_x_size * (cursor_y + scroll_amount) + cursor_x;
+ text_ram_write_data = space_char;
+ tty_busy <= 0;
+ state <= 2;
+ cursor_x <= 0;
+ end
+ end
+ 4: begin
+ if(tty_write) begin
+ case (tty_data)
+ 'h52: begin // "R": reset
+ tty_busy <= 1;
+ state <= 0;
+ end
+ left_bracket_char: begin
+ tty_busy <= 0;
+ state <= 5;
+ end
+ default: begin
+ text_ram_write_enable = 1;
+ text_ram_write_address = ram_x_size * (cursor_y + scroll_amount) + cursor_x;
+ text_ram_write_data = tty_data;
+ if(cursor_x != text_x_size - 1) begin
+ cursor_x <= cursor_x + 1;
+ tty_busy <= 0;
+ state <= 2;
+ end
+ else if(cursor_y != text_y_size - 1) begin
+ cursor_x <= 0;
+ cursor_y <= cursor_y + 1;
+ tty_busy <= 0;
+ state <= 2;
+ end
+ else begin
+ cursor_x <= 0;
+ cursor_y <= text_y_size - 1;
+ tty_busy <= 1;
+ state <= 3;
+ scroll_amount <= scroll_amount + 1;
+ end
+ end
+ endcase
+ end
+ else begin
+ tty_busy <= 0;
+ end
+ end
+ 5: begin
+ if(tty_write) begin
+ case (tty_data)
+ capital_H_char: begin // move to top left
+ tty_busy <= 0;
+ state <= 2;
+ cursor_x <= 0;
+ cursor_y <= 0;
+ end
+ default: begin
+ text_ram_write_enable = 1;
+ text_ram_write_address = ram_x_size * (cursor_y + scroll_amount) + cursor_x;
+ text_ram_write_data = tty_data;
+ if(cursor_x != text_x_size - 1) begin
+ cursor_x <= cursor_x + 1;
+ tty_busy <= 0;
+ state <= 2;
+ end
+ else if(cursor_y != text_y_size - 1) begin
+ cursor_x <= 0;
+ cursor_y <= cursor_y + 1;
+ tty_busy <= 0;
+ state <= 2;
+ end
+ else begin
+ cursor_x <= 0;
+ cursor_y <= text_y_size - 1;
+ tty_busy <= 1;
+ state <= 3;
+ scroll_amount <= scroll_amount + 1;
+ end
+ end
+ endcase
+ end
+ else begin
+ tty_busy <= 0;
+ end
+ end
+ default: state <= 0;
+ endcase
+ end
+
+endmodule