From 0553c4839c06011bd044f69b4913e5c793fdd2ec Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 27 Feb 2022 17:21:05 -0800 Subject: Initial commit. --- .gitignore | 4 + Makefile | 38 + PLAN | 20 + altera/clocks.sdc | 3 + altera/jtag.cdf | 12 + hdl/command_parser.sv | 109 ++ hdl/core.sv | 856 ++++++++++ hdl/defs.svh | 58 + hdl/echo_arbiter.sv | 64 + hdl/front_panel.sv | 211 +++ hdl/pll.sv | 126 ++ hdl/ram_controller.sv | 240 +++ hdl/result_printer.sv | 71 + hdl/top.sv | 298 ++++ mem/focal69.loaded.hex | 4096 ++++++++++++++++++++++++++++++++++++++++++++++++ mem/hello.pal | 45 + tcl/clean.tcl | 3 + tcl/init.tcl | 107 ++ 18 files changed, 6361 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 PLAN create mode 100644 altera/clocks.sdc create mode 100644 altera/jtag.cdf create mode 100644 hdl/command_parser.sv create mode 100644 hdl/core.sv create mode 100644 hdl/defs.svh create mode 100644 hdl/echo_arbiter.sv create mode 100644 hdl/front_panel.sv create mode 100644 hdl/pll.sv create mode 100644 hdl/ram_controller.sv create mode 100644 hdl/result_printer.sv create mode 100644 hdl/top.sv create mode 100644 mem/focal69.loaded.hex create mode 100644 mem/hello.pal create mode 100644 tcl/clean.tcl create mode 100644 tcl/init.tcl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..298becb --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/build +/db +/incremental_db +/pdp8.* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0250933 --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ +SOURCES := $(wildcard hdl/**.sv) +HEADERS := $(wildcard hdl/**.svh) +MEMORIES := $(addprefix build/, $(addsuffix .hex, $(basename $(wildcard mem/**.pal)))) +QUARTUS := $(shell find altera tcl -name \*.cdf -o -name \*.sdc -o -name \*.tcl) + +fpga: pdp8.sof + quartus_pgm -c 1 -m JTAG -o "P;$<@1" +.PHONY: fpga + +term-mem: + nios2-terminal --instance 0 +.PHONY: term-mem + +term-pdp8: + nios2-terminal --instance 1 +.PHONY: term-pdp8 + +build/%.hex: build/%.bin + p8bin2hex $< > $@ + +build/%.hex: %.bin + p8bin2hex $< > $@ + +build/%.bin: %.pal + @mkdir -p $(dir $@) + palbart $< + mv -f $*.bin $*.lst $(dir $@) + +pdp8.sof: $(SOURCES) $(HEADERS) $(MEMORIES) $(QUARTUS) + [ ! -e pdp8.qpf ] || quartus_sh -t tcl/clean.tcl + quartus_sh -t tcl/init.tcl + quartus_sh --flow compile pdp8.qpf + +clean: + git clean -dfX +.PHONY: clean + +.SECONDARY: diff --git a/PLAN b/PLAN new file mode 100644 index 0000000..d60dec5 --- /dev/null +++ b/PLAN @@ -0,0 +1,20 @@ +1. fix hello.pal (in noncpu) +2. fix hello.pal (in multipdp8) (it only sees bytes with the lowest bit set) + + +---------+ + +-----+ Arbiter <-----------------------------------------------+ + | +-^-------+ | + | | | + | | | + | | | ++------v-+ +-+--------------+ +-+--------------+ +| UART 0 +---> Command Parser +-----+ | Result Printer | ++--------+ +----------------+ | +-^--------------+ + | | + +-------+ | +----------------+ | + | Cache | | | Another Cache | | ++--------+ +-------+ +-v-------+ +----------------+ +-+-----------+ +| UART 1 +---> PDP-8 +------------> Arbiter +---> RAM Controller +---> Broadcaster | ++--------+ +-----^-+ +---------+ +----------------+ +-+-----------+ + | | + +---------------------------------------------------+ diff --git a/altera/clocks.sdc b/altera/clocks.sdc new file mode 100644 index 0000000..c08f897 --- /dev/null +++ b/altera/clocks.sdc @@ -0,0 +1,3 @@ +# This is the clock for timing analysis, not timing-driven synthesis. +# See init.tcl for the other clock. +create_clock -period "50 MHz" clock diff --git a/altera/jtag.cdf b/altera/jtag.cdf new file mode 100644 index 0000000..ac80090 --- /dev/null +++ b/altera/jtag.cdf @@ -0,0 +1,12 @@ +JedecChain; + FileRevision(JESD32A); + DefaultMfr(6E); + + P ActionCode(Ign) + Device PartName(10CL025Y) MfrSpec(OpMask(0)); + +ChainEnd; + +AlteraBegin; + ChainType(JTAG); +AlteraEnd; diff --git a/hdl/command_parser.sv b/hdl/command_parser.sv new file mode 100644 index 0000000..5c49db9 --- /dev/null +++ b/hdl/command_parser.sv @@ -0,0 +1,109 @@ +`include "defs.svh" + +module command_parser + #( TAG = 0 + ) ( input bit clock + , input bit reset + + , output bit uart_ready + , input bit uart_valid + , input uart_byte_t uart_data + + , input bit echo_ready + , output bit echo_valid + , output uart_byte_t echo_data + + , input bit command_ready + , output bit command_valid + , output ram_command_t command_data + ); + + bit input_byte_valid; + uart_byte_t input_byte; + + (* syn_encoding = "one-hot" *) enum int unsigned + { READ_ADDRESS_OR_COMMAND + , READ_DATA + } state; + + always @(posedge clock) begin + if (reset) begin + uart_ready = 0; + command_valid = 0; + input_byte_valid = 0; + input_byte = 0; + state = state.first; + end else begin + if (echo_ready) echo_valid = 0; + if (command_ready && command_valid) begin + command_valid = 0; + command_data.address = 0; + command_data.write = 0; + for (int i = 0; i < `RAM_LINE_WORDS; i = i + 1) begin + command_data.data[i] = 0; + command_data.mask[i] = ~0; + end + command_data.tag = TAG; + end + if (uart_ready && uart_valid) begin + echo_valid = 1; + echo_data = uart_data; + input_byte_valid = 1; + input_byte = uart_data; + end + + if (!command_valid && input_byte_valid) begin + case (state) + + READ_ADDRESS_OR_COMMAND: begin + if (input_byte >= "0" && input_byte <= "9") begin + command_data.address = command_data.address << 4; + command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "0"; + end else if (input_byte >= "a" && input_byte <= "f") begin + command_data.address = command_data.address << 4; + command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "a" + 10; + end else if (input_byte >= "A" && input_byte <= "F") begin + command_data.address = command_data.address << 4; + command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "A" + 10; + end else if (input_byte == "?") begin + command_valid = 1; + command_data.write = 0; + command_data.data = 0; + end else if (input_byte == "=") begin + command_data.write = 1; + command_data.data = 0; + state = READ_DATA; + end else begin + command_data.address = 0; + command_data.write = 0; + command_data.data = 0; + end + end + + READ_DATA: begin + automatic bit [$bits(command_data.data)-1:0] flat_data = command_data.data; + flat_data = flat_data << 4; + if (input_byte >= "0" && input_byte <= "9") begin + flat_data[3:0] = input_byte - "0"; + command_data.data = flat_data; + end else if (input_byte >= "a" && input_byte <= "f") begin + flat_data[3:0] = input_byte - "a" + 10; + command_data.data = flat_data; + end else if (input_byte >= "A" && input_byte <= "F") begin + flat_data[3:0] = input_byte - "A" + 10; + command_data.data = flat_data; + end else begin + command_valid = 1; + state = state.first; + end + end + + endcase + input_byte_valid = 0; + end + + uart_ready = !echo_valid && !input_byte_valid; + end + end + +endmodule diff --git a/hdl/core.sv b/hdl/core.sv new file mode 100644 index 0000000..17b753d --- /dev/null +++ b/hdl/core.sv @@ -0,0 +1,856 @@ +`ifdef SYNTHESIS +`define lag(x) x +`else +`define lag(x) $past(x) +`endif + +module mem + ( input bit clk + , input bit reset + + , output bit ready + , input bit valid + , input bit write + , input bit [ADDR_BITS-1:0] address + , input bit [DATA_BITS-1:0] write_data + + , output bit read_valid + , output bit [DATA_BITS-1:0] read_data + ); + +parameter ADDR_BITS; +parameter DATA_BITS; +parameter INIT_FILE; + +bit [DATA_BITS-1:0] storage [0:(1<= 26000) $finish; + end +`endif + end + + if (switch_sing_step) + run = 0; + + if (state == FETCH && switch_sing_inst) + run = 0; + + rx_ready = !tti_valid; + end + end +end + +endmodule diff --git a/hdl/defs.svh b/hdl/defs.svh new file mode 100644 index 0000000..ea8dbc1 --- /dev/null +++ b/hdl/defs.svh @@ -0,0 +1,58 @@ +`define RAM_ADDRESS_BITS 23 +`define RAM_BYTE_BITS 8 +`define RAM_WORD_BYTES 2 +`define RAM_LINE_WORDS 1 + +`define PDP_ADDRESS_BITS 15 + +`define UART_BYTE_BITS 8 + +`define TAG_BITS 1 + +typedef bit [`RAM_ADDRESS_BITS-1:0] ram_word_address_t; +typedef bit [`RAM_ADDRESS_BITS-1:$clog2(`RAM_LINE_WORDS)] ram_line_address_t; +typedef bit [`RAM_BYTE_BITS-1:0] ram_byte_t; +typedef ram_byte_t [`RAM_WORD_BYTES-1:0] ram_word_t; +typedef ram_word_t [`RAM_LINE_WORDS-1:0] ram_line_t; +typedef bit [$clog2(`RAM_WORD_BYTES):0] ram_word_mask_t; +typedef ram_word_mask_t [`RAM_LINE_WORDS-1:0] ram_line_mask_t; + +typedef bit [$clog2(`RAM_WORD_BYTES+1):0] ram_byte_count_t; +typedef bit [$clog2(`RAM_LINE_WORDS+1):0] ram_word_count_t; + +typedef bit [`RAM_ADDRESS_BITS-1:`PDP_ADDRESS_BITS] ram_pdp_address_space_t; + +typedef bit [`PDP_ADDRESS_BITS-1:0] pdp_word_address_t; +typedef bit [`PDP_ADDRESS_BITS-1:$clog2(`RAM_LINE_WORDS)] pdp_line_address_t; + +typedef bit [`TAG_BITS-1:0] tag_t; + +typedef bit [`UART_BYTE_BITS-1:0] uart_byte_t; + +typedef struct { + ram_line_address_t address; + bit write; + ram_line_t data; + ram_line_mask_t mask; + tag_t tag; +} ram_command_t; + +typedef struct { + ram_line_address_t address; + ram_line_t data; + tag_t tag; +} ram_read_response_t; + +typedef struct { + pdp_line_address_t address; + bit write; + ram_line_t data; + ram_line_mask_t mask; + tag_t tag; +} pdp_command_t; + +typedef struct { + pdp_line_address_t address; + ram_line_t data; + tag_t tag; +} pdp_read_response_t; diff --git a/hdl/echo_arbiter.sv b/hdl/echo_arbiter.sv new file mode 100644 index 0000000..1c27e31 --- /dev/null +++ b/hdl/echo_arbiter.sv @@ -0,0 +1,64 @@ +`include "defs.svh" + +module echo_arbiter + ( input bit clock + , input bit reset + + , output bit in0_ready + , input bit in0_valid + , input uart_byte_t in0_data + + , output bit in1_ready + , input bit in1_valid + , input uart_byte_t in1_data + + , input bit out_ready + , output bit out_valid + , output uart_byte_t out_data + ); + + bit in0_hold_valid; + uart_byte_t in0_hold; + + bit in1_hold_valid; + uart_byte_t in1_hold; + + always @(posedge clock) begin + if (reset) begin + in0_ready = 0; + in1_ready = 0; + out_valid = 0; + out_data = 0; + in0_hold_valid = 0; + in0_hold = 0; + in1_hold_valid = 0; + in1_hold = 0; + end else begin + if (out_ready) out_valid = 0; + if (in0_ready && in0_valid) begin + in0_hold_valid = 1; + in0_hold = in0_data; + end + if (in1_ready && in1_valid) begin + in1_hold_valid = 1; + in1_hold = in1_data; + end + + if (!out_valid) begin + if (in0_hold_valid) begin + out_valid = 1; + out_data = in0_hold; + in0_hold_valid = 0; + end else if (in1_hold_valid) begin + out_valid = 1; + out_data = in1_hold; + in1_hold_valid = 0; + end + end + + in0_ready = !in0_hold_valid; + in1_ready = !in1_hold_valid; + end + end + +endmodule diff --git a/hdl/front_panel.sv b/hdl/front_panel.sv new file mode 100644 index 0000000..52b4bdb --- /dev/null +++ b/hdl/front_panel.sv @@ -0,0 +1,211 @@ +module front_panel + #( DEBOUNCE_MAX = 100 + ) + ( input bit clk + , input bit reset + + , input bit [8:1][12:1] led + , output bit [3:1][12:1] switch + + , inout wire [10:1] gpioa + , inout wire [28:13] gpiob + , inout wire [40:31] gpioc + ); + +localparam DEBOUNCE_BITS = $clog2(DEBOUNCE_MAX+1); + +enum + { LED_ROW1 + , DEAD_ROW2 + , LED_ROW2 + , DEAD_ROW3 + , LED_ROW3 + , DEAD_ROW4 + , LED_ROW4 + , DEAD_ROW5 + , LED_ROW5 + , DEAD_ROW6 + , LED_ROW6 + , DEAD_ROW7 + , LED_ROW7 + , DEAD_ROW8 + , LED_ROW8 + , DEAD_ROW9 + , SWITCH_PREP + , SWITCH_ROW1 + , SWITCH_ROW2 + , SWITCH_ROW3 + } state; + +bit [3:1][12:1] switch_raw; +bit [DEBOUNCE_BITS-1:0] switch_debounce; + +`define LEDROW1 gpioc[38] +`define LEDROW2 gpioc[40] +`define LEDROW3 gpiob[15] +`define LEDROW4 gpiob[16] +`define LEDROW5 gpiob[18] +`define LEDROW6 gpiob[22] +`define LEDROW7 gpioc[37] +`define LEDROW8 gpiob[13] + +`define SWROW1 gpioc[36] +`define SWROW2 gpioa[1] +`define SWROW3 gpioa[2] + +`define COL1 gpioa[8] +`define COL2 gpioa[10] +`define COL3 gpioa[7] +`define COL4 gpiob[27] +`define COL5 gpioc[31] +`define COL6 gpiob[26] +`define COL7 gpiob[24] +`define COL8 gpiob[21] +`define COL9 gpiob[19] +`define COL10 gpiob[23] +`define COL11 gpioc[32] +`define COL12 gpioc[33] + +`define DO_LEDS +`define DO_SWITCHES + +always_ff @(posedge clk) begin + // LED rows (active high) + `LEDROW1 = 1'b0; + `LEDROW2 = 1'b0; + `LEDROW3 = 1'b0; + `LEDROW4 = 1'b0; + `LEDROW5 = 1'b0; + `LEDROW6 = 1'b0; + `LEDROW7 = 1'b0; + `LEDROW8 = 1'b0; + + // Switch rows (active low) + `SWROW1 = 1'b1; + `SWROW2 = 1'b1; + `SWROW3 = 1'b1; + + if (reset) begin + switch = 0; + switch_raw = 0; + switch_debounce = 0; + state = state.first; + end else begin + automatic bit [3:1][12:1] new_switch = switch_raw; + + case (state) +`ifdef DO_LEDS +`define LED_ROW(n) \ + LED_ROW``n: begin \ + `LEDROW``n = 1'b1; \ + `COL1 = ~led[n][1]; \ + `COL2 = ~led[n][2]; \ + `COL3 = ~led[n][3]; \ + `COL4 = ~led[n][4]; \ + `COL5 = ~led[n][5]; \ + `COL6 = ~led[n][6]; \ + `COL7 = ~led[n][7]; \ + `COL8 = ~led[n][8]; \ + `COL9 = ~led[n][9]; \ + `COL10 = ~led[n][10]; \ + `COL11 = ~led[n][11]; \ + `COL12 = ~led[n][12]; \ + end + + `LED_ROW(1) + `LED_ROW(2) + `LED_ROW(3) + `LED_ROW(4) + `LED_ROW(5) + `LED_ROW(6) + `LED_ROW(7) + `LED_ROW(8) +`endif + +`ifdef DO_SWITCHES + SWITCH_PREP: begin + `SWROW1 = 1'b0; + + `COL1 = 1'bZ; + `COL2 = 1'bZ; + `COL3 = 1'bZ; + `COL4 = 1'bZ; + `COL5 = 1'bZ; + `COL6 = 1'bZ; + `COL7 = 1'bZ; + `COL8 = 1'bZ; + `COL9 = 1'bZ; + `COL10 = 1'bZ; + `COL11 = 1'bZ; + `COL12 = 1'bZ; + end + + SWITCH_ROW1: begin + `SWROW2 = 1'b0; + + new_switch[1][1] = ~`COL1; + new_switch[1][2] = ~`COL2; + new_switch[1][3] = ~`COL3; + new_switch[1][4] = ~`COL4; + new_switch[1][5] = ~`COL5; + new_switch[1][6] = ~`COL6; + new_switch[1][7] = ~`COL7; + new_switch[1][8] = ~`COL8; + new_switch[1][9] = ~`COL9; + new_switch[1][10] = ~`COL10; + new_switch[1][11] = ~`COL11; + new_switch[1][12] = ~`COL12; + end + + SWITCH_ROW2: begin + `SWROW3 = 1'b0; + + new_switch[2][1] = ~`COL1; + new_switch[2][2] = ~`COL2; + new_switch[2][3] = ~`COL3; + new_switch[2][4] = ~`COL4; + new_switch[2][5] = ~`COL5; + new_switch[2][6] = ~`COL6; + new_switch[2][7] = ~`COL7; + new_switch[2][8] = ~`COL8; + new_switch[2][9] = ~`COL9; + new_switch[2][10] = ~`COL10; + new_switch[2][11] = ~`COL11; + new_switch[2][12] = ~`COL12; + end + + SWITCH_ROW3: begin + new_switch[3][1] = ~`COL1; + new_switch[3][2] = ~`COL2; + new_switch[3][3] = ~`COL3; + new_switch[3][4] = ~`COL4; + new_switch[3][5] = ~`COL5; + new_switch[3][6] = ~`COL6; + new_switch[3][7] = ~`COL7; + new_switch[3][8] = ~`COL8; + new_switch[3][9] = ~`COL9; + new_switch[3][10] = ~`COL10; + new_switch[3][11] = ~`COL11; + new_switch[3][12] = ~`COL12; + end +`endif + endcase + + if (state == state.last) + state = state.first; + else + state = state.next; + + if (new_switch == switch_raw) begin + if (switch_debounce == 0) + switch = switch_raw; + else + --switch_debounce; + end else begin + switch_raw = new_switch; + switch_debounce = DEBOUNCE_MAX; + end + end +end + +endmodule diff --git a/hdl/pll.sv b/hdl/pll.sv new file mode 100644 index 0000000..d348b7c --- /dev/null +++ b/hdl/pll.sv @@ -0,0 +1,126 @@ +module pll + #( MULTIPLY_BY = 1 + , DIVIDE_BY = 1 + , NATIVE_PERIOD_PICOSECONDS = 20_000 + ) + ( input bit native_clk + , input bit reset_n + + , output bit target_clk + , output bit reset + ); + +enum + { NOT_LOCKED + , RESET_CYCLE + , READY + } state = state.first; + +bit locked; + +`ifndef SYNTHESIS + +assign target_clk = native_clk; +assign locked = 1; + +`else + +altpll + #( .clk0_divide_by(DIVIDE_BY) + , .clk0_multiply_by(MULTIPLY_BY) + , .inclk0_input_frequency(NATIVE_PERIOD_PICOSECONDS) + , .intended_device_family("Cyclone 10 LP") + , .operation_mode("NORMAL") + , .port_activeclock("PORT_UNUSED") + , .port_areset("PORT_USED") + , .port_clkbad0("PORT_UNUSED") + , .port_clkbad1("PORT_UNUSED") + , .port_clkloss("PORT_UNUSED") + , .port_clkswitch("PORT_UNUSED") + , .port_configupdate("PORT_UNUSED") + , .port_fbin("PORT_UNUSED") + , .port_inclk0("PORT_USED") + , .port_inclk1("PORT_UNUSED") + , .port_locked("PORT_USED") + , .port_pfdena("PORT_UNUSED") + , .port_phasecounterselect("PORT_UNUSED") + , .port_phasedone("PORT_UNUSED") + , .port_phasestep("PORT_UNUSED") + , .port_phaseupdown("PORT_UNUSED") + , .port_pllena("PORT_UNUSED") + , .port_scanaclr("PORT_UNUSED") + , .port_scanclk("PORT_UNUSED") + , .port_scanclkena("PORT_UNUSED") + , .port_scandata("PORT_UNUSED") + , .port_scandataout("PORT_UNUSED") + , .port_scandone("PORT_UNUSED") + , .port_scanread("PORT_UNUSED") + , .port_scanwrite("PORT_UNUSED") + , .port_clk0("PORT_USED") + , .port_clk1("PORT_UNUSED") + , .port_clk2("PORT_UNUSED") + , .port_clk3("PORT_UNUSED") + , .port_clk4("PORT_UNUSED") + , .port_clk5("PORT_UNUSED") + , .port_clkena0("PORT_UNUSED") + , .port_clkena1("PORT_UNUSED") + , .port_clkena2("PORT_UNUSED") + , .port_clkena3("PORT_UNUSED") + , .port_clkena4("PORT_UNUSED") + , .port_clkena5("PORT_UNUSED") + , .port_extclk0("PORT_UNUSED") + , .port_extclk1("PORT_UNUSED") + , .port_extclk2("PORT_UNUSED") + , .port_extclk3("PORT_UNUSED") + , .self_reset_on_loss_lock("ON") + , .width_clock(5) + ) pll + ( .areset(!reset_n) + , .inclk(native_clk) + , .clk(target_clk) + , .locked(locked) + , .activeclock() + , .clkbad() + , .clkena({6{1'b1}}) + , .clkloss() + , .clkswitch(1'b0) + , .configupdate(1'b0) + , .extclkena({4{1'b1}}) + , .fbin(1'b1) + , .fbmimicbidir() + , .fbout() + , .fref() + , .icdrclk() + , .pfdena(1'b1) + , .phasecounterselect({4{1'b1}}) + , .phasedone() + , .phasestep(1'b1) + , .phaseupdown(1'b1) + , .pllena(1'b1) + , .scanaclr(1'b0) + , .scanclk(1'b0) + , .scanclkena(1'b1) + , .scandata(1'b0) + , .scandataout() + , .scandone() + , .scanread(1'b0) + , .scanwrite(1'b0) + , .sclkout0() + , .sclkout1() + , .vcooverrange() + , .vcounderrange() + ); + +`endif + +always_ff @(posedge target_clk) begin + if (!reset_n || !locked) begin + state = state.first; + end else if (state != state.last) begin + state = state.next; + end + + reset = !(state == state.last); +end + +endmodule diff --git a/hdl/ram_controller.sv b/hdl/ram_controller.sv new file mode 100644 index 0000000..6eeb46d --- /dev/null +++ b/hdl/ram_controller.sv @@ -0,0 +1,240 @@ +`include "defs.svh" + +module ram_controller + ( input bit clock + , input bit reset + + , output bit command_ready + , input bit command_valid + , input ram_command_t command_data + + , input bit result_ready + , output bit result_valid + , output ram_read_response_t result_data + + , output bit ram_resetn + , output bit ram_csn + , output bit ram_clkp + , output bit ram_clkn + , output bit ram_rwds_oe + , input bit ram_rwds_in + , output bit ram_rwds_out + , output bit ram_data_oe + , input bit [7:0] ram_data_in + , output bit [7:0] ram_data_out + ); + + assign ram_clkn = !ram_clkp; + + bit valid; + ram_command_t command; + ram_word_address_t base_address; + + bit slow; + ram_word_count_t word_count; + + (* syn_encoding = "one-hot" *) enum int unsigned + { CHIP_SELECT + + , SEND_COMMAND_1 + , SEND_COMMAND_2 + , SEND_COMMAND_3 + , SEND_COMMAND_4 + , SEND_COMMAND_5 + , SEND_COMMAND_6 + + , LAT2_12 + , LAT2_11 + , LAT2_10 + , LAT2_9 + , LAT2_8 + , LAT2_7 + , LAT2_6 + , LAT2_5 + , LAT2_4 + , LAT2_3 + , LAT2_2 + , LAT2_1 + + /* Latency blocks are 6 cycle, but you start counting after the upper + * column address is sent (SEND_COMMAND_4) so we reduce the + * lowest-latency block by one full cycle (two states). + , LAT1_12 + , LAT1_11 + */ + , LAT1_10 + , LAT1_9 + , LAT1_8 + , LAT1_7 + , LAT1_6 + , LAT1_5 + , LAT1_4 + , LAT1_3 + , LAT1_2 + , LAT1_1 + + , DATA_1 + , DATA_2 + } state; + + (* syn_encoding = "compact" *) enum bit + { SETUP_OUTPUTS + , TOGGLE_CLOCK + } half_state; + + bit [2:0] reset_counter; + + bit prev_rwds; + + always @(posedge clock) begin + if (reset || reset_counter != 0) begin + command_ready = 0; + result_valid = 0; + ram_resetn = 0; + ram_csn = 1; + ram_clkp = 0; + ram_rwds_oe = 0; + ram_rwds_out = 0; + ram_data_oe = 0; + ram_data_out = 0; + base_address = 0; + slow = 0; + word_count = `RAM_LINE_WORDS; + state = state.first; + half_state = half_state.first; + if (reset) + reset_counter = 5; // Spec wants >= 100ns of reset + else + reset_counter = reset_counter - 1; + end else begin + ram_resetn = 1; + + if (result_ready) result_valid = 0; + if (command_ready && command_valid) begin + valid = 1; + command = command_data; + base_address = 0; + base_address[`RAM_ADDRESS_BITS-1:$clog2(`RAM_LINE_WORDS)] = command.address; + word_count = `RAM_LINE_WORDS; + state = state.first; + end + + if (!valid) begin + ram_rwds_oe = 0; + ram_data_oe = 0; + ram_csn = 1; + ram_clkp = 0; + end else if (half_state == TOGGLE_CLOCK) begin + half_state = half_state.next; + if (state != CHIP_SELECT && state != SEND_COMMAND_1) + ram_clkp = !ram_clkp; + end else if (half_state == SETUP_OUTPUTS) begin + automatic bit stall = 0; + half_state = half_state.next; + ram_rwds_oe = 0; + ram_data_oe = 0; + case (state) + + CHIP_SELECT: begin + ram_clkp = 0; // Overriding clock to guarantee that we're starting the command with the correct clock polarity + ram_csn = 0; + end + + SEND_COMMAND_1: begin + ram_data_oe = 1; + ram_data_out = {!command.write, 1'b0, 1'b1, 5'b0}; // R/W#, ADDRSPACE, BURST, RESERVED + end + + SEND_COMMAND_2: begin + ram_data_oe = 1; + ram_data_out = {4'b0, base_address[22:19]}; // RESERVED, ROW + end + + SEND_COMMAND_3: begin + ram_data_oe = 1; + ram_data_out = {base_address[18:11]}; // ROW + end + + SEND_COMMAND_4: begin + ram_data_oe = 1; + ram_data_out = {base_address[10:9], base_address[8:3]}; // ROW, UPPERCOL + // This is the cycle immediately before the latency countdown *really* begins. + // So we capture RWDS now in order to know how many latency blocks are required. + slow = ram_rwds_in; + end + + SEND_COMMAND_5: begin + ram_data_oe = 1; + ram_data_out = {8'b0}; // RESERVED + end + + SEND_COMMAND_6: begin + ram_data_oe = 1; + ram_data_out = {5'b0, base_address[2:0]}; // RESERVED, LOWERCOL + // If we're not in "slow" mode then skip the LAT2 latency + // block. Note that the state=state.next will still happen + // below, taking us to the first state in the LAT1 block. + if (!slow) state = LAT2_1; + end + + // Nothing happens on any of the LAT_* states except for + // cycling the clock and advancing state. + + DATA_1: begin + if (command.write) begin + ram_rwds_oe = 1; + ram_rwds_out = !command.mask[word_count - 1][0]; + ram_data_oe = 1; + ram_data_out = command.data[word_count - 1][0]; + end else if (prev_rwds != ram_rwds_in) begin + command.data[word_count - 1][0] = ram_data_in; + end else begin + stall = 1; + end + end + + DATA_2: begin + if (command.write) begin + ram_rwds_oe = 1; + ram_rwds_out = !command.mask[word_count - 1][1]; + ram_data_oe = 1; + ram_data_out = command.data[word_count - 1][1]; + word_count = word_count - 1; + if (word_count != 0) begin + stall = 1; + state = DATA_1; + end + end else if (prev_rwds != ram_rwds_in) begin + command.data[word_count - 1][1] = ram_data_in; + word_count = word_count - 1; + if (word_count != 0) begin + stall = 1; + state = DATA_1; + end + end else begin + stall = 1; + end + end + + endcase + if (!stall) begin + state = state.next; + if (state == state.first) begin + valid = 0; + if (!command.write) begin + // We know that this is safe because we don't accept commands unless we have result bandwidth + result_valid = 1; + result_data.address = command.address; + result_data.data = command.data; + result_data.tag = command.tag; + end + end + end + end + + prev_rwds = ram_rwds_in; + command_ready = !valid && !result_valid; + end + end + +endmodule diff --git a/hdl/result_printer.sv b/hdl/result_printer.sv new file mode 100644 index 0000000..3041e6e --- /dev/null +++ b/hdl/result_printer.sv @@ -0,0 +1,71 @@ +`include "defs.svh" + +module result_printer + #( TAG = 0 + ) ( input bit clock + , input bit reset + + , output bit result_ready + , input bit result_valid + , input ram_read_response_t result_data + + , input bit echo_ready + , output bit echo_valid + , output uart_byte_t echo_data + ); + + ram_read_response_t hold; + ram_byte_count_t byte_count; + ram_word_count_t word_count; + + (* syn_encoding = "one-hot" *) enum int unsigned + { HIGH_NIBBLE + , LOW_NIBBLE + } state; + + always @(posedge clock) begin + if (reset) begin + result_ready = 0; + echo_valid = 0; + echo_data = 0; + byte_count = 0; + word_count = 0; + state = state.first; + end else begin + if (echo_ready) echo_valid = 0; + if (result_ready && result_valid) begin + hold = result_data; + if (hold.tag == TAG) begin + byte_count = `RAM_WORD_BYTES; + word_count = `RAM_LINE_WORDS; + state = state.first; + end + end + + if (word_count != 0 && !echo_valid) begin + automatic ram_word_t w = hold.data[word_count-1]; + automatic ram_byte_t b = w[byte_count-1]; + echo_valid = 1; + case (state) + HIGH_NIBBLE: echo_data = b[7:4]; + LOW_NIBBLE: echo_data = b[3:0]; + endcase + if (echo_data < 10) + echo_data = echo_data + "0"; + else + echo_data = echo_data + "A" - 10; + state = state.next; + if (state == state.first) begin + byte_count = byte_count - 1; + if (byte_count == 0) begin + byte_count = `RAM_WORD_BYTES; + word_count = word_count - 1; + end + end + end + + result_ready = word_count == 0; + end + end + +endmodule diff --git a/hdl/top.sv b/hdl/top.sv new file mode 100644 index 0000000..7ec57b7 --- /dev/null +++ b/hdl/top.sv @@ -0,0 +1,298 @@ +`include "defs.svh" + +module top + ( input bit clock + , input bit resetn + + , inout wire [10:1] gpioa + , inout wire [28:13] gpiob + , inout wire [40:31] gpioc + + , output bit ram_resetn + , output bit ram_csn + , output bit ram_clkp + , output bit ram_clkn + , inout bit ram_rwds + , inout bit [7:0] ram_data + ); + + bit internal_clock; + bit internal_reset; + pll + #( .MULTIPLY_BY(1) + , .DIVIDE_BY(1) + ) fastpll + ( .native_clk(clock) + , .reset_n(resetn) + , .target_clk(internal_clock) + , .reset(internal_reset) + ); + + bit ram_rx_ready; + bit ram_rx_valid; + uart_byte_t ram_rx_data; + + bit ram_tx_ready; + bit ram_tx_valid; + uart_byte_t ram_tx_data; + + bit ram_echo_in0_ready; + bit ram_echo_in0_valid; + uart_byte_t ram_echo_in0_data; + + bit ram_echo_in1_ready; + bit ram_echo_in1_valid; + uart_byte_t ram_echo_in1_data; + + bit command_ready; + bit command_valid; + ram_command_t command_data; + + bit result_ready; + bit result_valid; + ram_read_response_t result_data; + + bit ram_rwds_oe; + bit ram_rwds_out; + assign ram_rwds = ram_rwds_oe ? ram_rwds_out : 1'bZ; + + bit ram_data_oe; + bit [7:0] ram_data_out; + assign ram_data = ram_data_oe ? ram_data_out : 8'bZ; + + alt_jtag_atlantic + #( .INSTANCE_ID(0) + , .LOG2_RXFIFO_DEPTH(6) + , .LOG2_TXFIFO_DEPTH(6) + , .SLD_AUTO_INSTANCE_INDEX("NO") + ) ram_jtag + ( .clk(internal_clock) + , .rst_n(!internal_reset) + + , .r_dat(ram_tx_data) + , .r_val(ram_tx_valid) + , .r_ena(ram_tx_ready) + + , .t_dat(ram_rx_data) + , .t_dav(ram_rx_ready) + , .t_ena(ram_rx_valid) + ); + + echo_arbiter arb + ( .clock(internal_clock) + , .reset(internal_reset) + + , .in0_ready(ram_echo_in0_ready) + , .in0_valid(ram_echo_in0_valid) + , .in0_data(ram_echo_in0_data) + + , .in1_ready(ram_echo_in1_ready) + , .in1_valid(ram_echo_in1_valid) + , .in1_data(ram_echo_in1_data) + + , .out_ready(ram_tx_ready) + , .out_valid(ram_tx_valid) + , .out_data(ram_tx_data) + ); + + command_parser + #( .TAG(0) + ) parser + ( .clock(internal_clock) + , .reset(internal_reset) + + , .uart_ready(ram_rx_ready) + , .uart_valid(ram_rx_valid) + , .uart_data(ram_rx_data) + + , .echo_ready(ram_echo_in0_ready) + , .echo_valid(ram_echo_in0_valid) + , .echo_data(ram_echo_in0_data) + + , .command_ready(command_ready) + , .command_valid(command_valid) + , .command_data(command_data) + ); + + ram_controller ram + ( .clock(internal_clock) + , .reset(internal_reset) + + , .command_ready(command_ready) + , .command_valid(command_valid) + , .command_data(command_data) + + , .result_ready(result_ready) + , .result_valid(result_valid) + , .result_data(result_data) + + , .ram_resetn(ram_resetn) + , .ram_csn(ram_csn) + , .ram_clkp(ram_clkp) + , .ram_clkn(ram_clkn) + , .ram_rwds_oe(ram_rwds_oe) + , .ram_rwds_in(ram_rwds) + , .ram_rwds_out(ram_rwds_out) + , .ram_data_oe(ram_data_oe) + , .ram_data_in(ram_data) + , .ram_data_out(ram_data_out) + ); + + result_printer + #( .TAG(0) + ) print + ( .clock(internal_clock) + , .reset(internal_reset) + + , .result_ready(result_ready) + , .result_valid(result_valid) + , .result_data(result_data) + + , .echo_ready(ram_echo_in1_ready) + , .echo_valid(ram_echo_in1_valid) + , .echo_data(ram_echo_in1_data) + ); + + bit slow_clock; + bit slow_reset; + pll + #( .MULTIPLY_BY(1) + , .DIVIDE_BY(500) + ) slowpll + ( .native_clk(clock) + , .reset_n(resetn) + , .target_clk(slow_clock) + , .reset(slow_reset) + ); + + bit [8:1][12:1] led; + bit [3:1][12:1] switch; + + front_panel panel + ( .clk(slow_clock) + , .reset(slow_reset) + + , .led(led) + , .switch(switch) + + , .gpioa(gpioa) + , .gpiob(gpiob) + , .gpioc(gpioc) + ); + + bit [2:0] switch_df; + bit [2:0] switch_if; + bit [11:0] switch_sr; + bit switch_start; + bit switch_load_add; + bit switch_dep; + bit switch_exam; + bit switch_cont; + bit switch_stop; + bit switch_sing_step; + bit switch_sing_inst; + + // Note that we are reversing the order here on a number of aggregates because + // the panel model gives us LEDs and switches in schematic-order, which is the + // opposite of the bit order + assign switch_df = {switch[2][1], switch[2][2], switch[2][3]}; + assign switch_if = {switch[2][4], switch[2][5], switch[2][6]}; + assign switch_sr = {switch[1][1], switch[1][2], switch[1][3], switch[1][4], switch[1][5], switch[1][6], switch[1][7], switch[1][8], switch[1][9], switch[1][10], switch[1][11], switch[1][12]}; + assign switch_start = switch[3][1]; + assign switch_load_add = switch[3][2]; + assign switch_dep = switch[3][3]; + assign switch_exam = switch[3][4]; + assign switch_cont = switch[3][5]; + assign switch_stop = switch[3][6]; + `ifdef HISTORIC_SWITCH_BEHAVIOUR + assign switch_sing_step = !switch[3][7]; + assign switch_sing_inst = !switch[3][8]; + `else + assign switch_sing_step = switch[3][7]; + assign switch_sing_inst = switch[3][8]; + `endif + + bit [11:0] led_pc; + bit [11:0] led_memaddr; + bit [11:0] led_memdata; + bit [11:0] led_acc; + bit [11:0] led_mq; + bit led_and; + bit led_tad; + bit led_isz; + bit led_dca; + bit led_jms; + bit led_jmp; + bit led_iot; + bit led_opr; + bit led_fetch; + bit led_execute; + bit led_defer; + bit led_word_count; + bit led_current_address; + bit led_break; + bit led_ion; + bit led_pause; + bit led_run; + bit [4:0] led_step_counter; + bit [2:0] led_df; + bit [2:0] led_if; + bit led_link; + + // Note that we are reversing the order here on a number of aggregates because + // the panel model gives us LEDs and switches in schematic-order, which is the + // opposite of the bit order + assign led[1] = {led_pc[0], led_pc[1], led_pc[2], led_pc[3], led_pc[4], led_pc[5], led_pc[6], led_pc[7], led_pc[8], led_pc[9], led_pc[10], led_pc[11]}; + assign led[2] = {led_memaddr[0], led_memaddr[1], led_memaddr[2], led_memaddr[3], led_memaddr[4], led_memaddr[5], led_memaddr[6], led_memaddr[7], led_memaddr[8], led_memaddr[9], led_memaddr[10], led_memaddr[11]}; + assign led[3] = {led_memdata[0], led_memdata[1], led_memdata[2], led_memdata[3], led_memdata[4], led_memdata[5], led_memdata[6], led_memdata[7], led_memdata[8], led_memdata[9], led_memdata[10], led_memdata[11]}; + assign led[4] = {led_acc[0], led_acc[1], led_acc[2], led_acc[3], led_acc[4], led_acc[5], led_acc[6], led_acc[7], led_acc[8], led_acc[9], led_acc[10], led_acc[11]}; + assign led[5] = {led_mq[0], led_mq[1], led_mq[2], led_mq[3], led_mq[4], led_mq[5], led_mq[6], led_mq[7], led_mq[8], led_mq[9], led_mq[10], led_mq[11]}; + assign led[6] = {led_word_count, led_defer, led_execute, led_fetch, led_opr, led_iot, led_jmp, led_jms, led_dca, led_isz, led_tad, led_and}; + assign led[7] = {2'b0, led_step_counter[4], led_step_counter[3], led_step_counter[2], led_step_counter[1], led_step_counter[0], led_run, led_pause, led_ion, led_break, led_current_address}; + assign led[8] = {5'b0, led_link, led_if[0], led_if[1], led_if[2], led_df[0], led_df[1], led_df[2]}; + + core cpu + ( .clk(internal_clock) + , .reset(internal_reset) + + , .switch_df(switch_df) + , .switch_if(switch_if) + , .switch_sr(switch_sr) + , .switch_start(switch_start) + , .switch_load_add(switch_load_add) + , .switch_dep(switch_dep) + , .switch_exam(switch_exam) + , .switch_cont(switch_cont) + , .switch_stop(switch_stop) + , .switch_sing_step(switch_sing_step) + , .switch_sing_inst(switch_sing_inst) + + , .led_pc(led_pc) + , .led_memaddr(led_memaddr) + , .led_memdata(led_memdata) + , .led_acc(led_acc) + , .led_mq(led_mq) + , .led_and(led_and) + , .led_tad(led_tad) + , .led_isz(led_isz) + , .led_dca(led_dca) + , .led_jms(led_jms) + , .led_jmp(led_jmp) + , .led_iot(led_iot) + , .led_opr(led_opr) + , .led_fetch(led_fetch) + , .led_execute(led_execute) + , .led_defer(led_defer) + , .led_word_count(led_word_count) + , .led_current_address(led_current_address) + , .led_break(led_break) + , .led_ion(led_ion) + , .led_pause(led_pause) + , .led_run(led_run) + , .led_step_counter(led_step_counter) + , .led_df(led_df) + , .led_if(led_if) + , .led_link(led_link) + ); + +endmodule diff --git a/mem/focal69.loaded.hex b/mem/focal69.loaded.hex new file mode 100644 index 0000000..13778e1 --- /dev/null +++ b/mem/focal69.loaded.hex @@ -0,0 +1,4096 @@ +003 +b03 +b03 +583 +004 +00b +040 +d00 +000 +000 +000 +8f8 +64f +000 +f02 +68d +000 +000 +507 +000 +000 +000 +001 +000 +000 +68f +000 +000 +000 +8f8 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +d83 +404 +dd4 +000 +000 +000 +ff0 +68f +2ec +50c +5be +5b6 +001 +08d +000 +005 +000 +08c +087 +083 +0df +08a +08d +f02 +fc0 +0ae +fc1 +f80 +ff0 +07f +00f +0bf +ffe +f3f +0b0 +f60 +f52 +f73 +ffd +ffb +ff7 +03f +080 +800 +418 +46d +bcd +c00 +c80 +660 +686 +660 +68f +40f +507 +151 +375 +13f +15c +16c +4bc +542 +2cc +1d1 +535 +46d +515 +0c2 +4a2 +4f0 +10b +34f +35b +41d +1e4 +1c0 +432 +5d6 +fc0 +0d8 +f87 +03f +ffa +fe6 +ffe +8f9 +f88 +b7e +25f +612 +e01 +640 +616 +296 +60b +295 +969 +25a +608 +632 +25a +617 +96a +967 +03b +13c +966 +a8f +0aa +690 +966 +966 +25a +60f +610 +965 +21d +60b +970 +971 +af2 +ab9 +416 +96c +254 +235 +fa0 +976 +230 +608 +632 +237 +708 +970 +f08 +965 +966 +236 +24e +fa0 +ab0 +975 +96e +a7f +960 +189 +312 +f28 +a7f +612 +212 +e01 +a9a +000 +970 +236 +24a +fa8 +ad2 +61e +9f9 +227 +0fa +226 +fa0 +976 +227 +96f +e04 +637 +971 +965 +971 +ae0 +aea +22c +e46 +22c +e04 +237 +637 +965 +971 +976 +aea +22c +237 +637 +965 +971 +ae0 +f08 +976 +e40 +237 +044 +fa0 +e10 +237 +046 +f30 +976 +fa0 +2fb +e10 +e04 +635 +bc2 +b80 +fe0 +400 +40c +408 +270 +262 +36b +2e3 +a00 +990 +a20 +a85 +a80 +f00 +5d5 +5d5 +5d5 +000 +e46 +e06 +e06 +b8b +96c +212 +962 +963 +00f +963 +035 +235 +fc8 +ab3 +96d +e00 +213 +609 +309 +973 +976 +960 +186 +964 +035 +312 +f28 +ab9 +e01 +618 +235 +fe0 +ab0 +318 +973 +ab9 +318 +637 +a95 +96d +976 +960 +188 +964 +035 +964 +00f +30b +612 +bbe +189 +000 +639 +e20 +8c8 +239 +70b +e20 +8c8 +bbf +000 +20b +60b +20b +e61 +219 +f98 +976 +bc8 +000 +3d1 +639 +e20 +8c8 +2d1 +e01 +70b +e20 +8c8 +b39 +000 +ea0 +3dc +609 +4dc +24f +8c8 +24f +639 +309 +70b +439 +ae5 +24f +8c8 +bdc +000 +ea0 +3ec +4ec +609 +24f +639 +30b +709 +439 +af3 +bec +5e0 +08a +08f +097 +23d +25f +5d5 +235 +188 +18c +f3a +96c +96d +976 +213 +612 +965 +236 +24e +fa8 +b61 +968 +2fe +a88 +236 +03d +962 +965 +968 +2fe +f08 +a93 +30b +967 +1fb +077 +976 +96c +416 +96d +ab7 +237 +fa0 +96b +965 +969 +236 +24e +fa0 +aa4 +313 +f28 +ab9 +e01 +618 +235 +fc0 +318 +973 +abb +318 +637 +a9f +213 +aab +616 +b61 +235 +fe8 +ab9 +969 +ab4 +000 +970 +968 +3f7 +bc0 +236 +4c0 +282 +fa8 +acf +971 +bc0 +f08 +bc0 +4c0 +4c0 +bc0 +000 +3d1 +60a +30a +f48 +ae0 +e21 +236 +fa0 +ad4 +3d1 +e20 +20a +62c +f08 +4d1 +4d1 +ec0 +bd1 +000 +044 +e21 +639 +237 +044 +239 +fa8 +4e4 +be4 +000 +21e +fa0 +af4 +965 +bee +96a +967 +dfe +702 +bee +21d +188 +18c +0d3 +0c6 +0c9 +0c4 +0c7 +0c3 +0c1 +0d4 +0cc +0c5 +0d7 +0cd +0d1 +0d2 +08a +974 +99f +40b +9a0 +249 +61a +225 +f48 +41a +fe8 +41a +f08 +bf7 +967 +2ff +ef9 +965 +a98 +965 +a95 +381 +427 +960 +303 +970 +236 +2dd +f20 +976 +218 +962 +960 +38a +30b +618 +907 +d18 +000 +967 +2ff +e7f +976 +218 +962 +960 +38a +967 +2ff +e7c +976 +963 +418 +960 +38a +963 +418 +963 +00f +960 +188 +964 +00f +964 +418 +964 +f38 +30b +618 +907 +118 +3db +d18 +555 +000 +225 +fe0 +b61 +218 +962 +963 +f38 +ac1 +f43 +f54 +963 +505 +ac1 +92b +962 +236 +2de +fa0 +976 +960 +38a +92b +c33 +e80 +30b +c2f +f08 +92b +e80 +b5e +221 +221 +20b +110 +183 +18c +282 +283 +f43 +484 +19d +2ae +07f +373 +cf1 +ea0 +62e +616 +967 +2f9 +07e +42e +a96 +960 +303 +236 +962 +2ad +969 +41e +e01 +959 +30b +636 +a82 +960 +38b +958 +a83 +416 +965 +967 +303 +1fb +969 +a9b +965 +96c +237 +62a +a84 +23f +933 +e20 +23f +969 +965 +a84 +0ba +96c +96d +976 +230 +608 +632 +237 +708 +208 +617 +934 +640 +416 +965 +969 +967 +03e +2b9 +966 +abb +230 +e01 +608 +632 +96a +967 +039 +2b9 +966 +ac6 +000 +f28 +236 +e21 +639 +3cc +4cc +60a +30a +f48 +ae0 +239 +fa0 +ad4 +20a +3cc +639 +339 +639 +b39 +4cc +ec0 +bcc +92b +e00 +cfd +cda +ae6 +cf2 +626 +c01 +b5e +000 +c26 +c16 +c21 +aef +e80 +bec +2bb +2b8 +5e0 +2c2 +2b9 +0b1 +2ca +0a5 +0a2 +0a1 +0a3 +0a4 +0a0 +0ac +0bb +08d +974 +0a2 +08d +976 +632 +966 +965 +968 +3f7 +a96 +236 +052 +231 +631 +965 +968 +3f7 +a96 +a91 +972 +a9f +231 +62e +9b0 +30b +631 +9af +92b +6cf +230 +618 +218 +e21 +219 +fe8 +ab1 +318 +e21 +231 +fa8 +ac5 +218 +238 +aa1 +427 +381 +219 +205 +e61 +20b +f90 +976 +219 +238 +619 +231 +718 +418 +2cf +718 +418 +907 +15f +d18 +000 +b61 +218 +609 +309 +e21 +2cf +fa0 +aac +418 +418 +b61 +000 +236 +24c +fa0 +bcf +965 +ad0 +f50 +f47 +000 +400 +000 +000 +236 +24d +fa0 +4db +236 +2d6 +62c +22c +fc8 +bdb +236 +2d7 +fe8 +4db +bdb +907 +2d8 +8e8 +cd8 +000 +6d8 +624 +b5e +25f +612 +30b +639 +b39 +2a1 +29a +2a9 +2a6 +62a +2ab +2ab +188 +18c +000 +22c +962 +22d +962 +22e +962 +281 +962 +965 +62d +974 +a97 +ada +ae3 +960 +307 +974 +aa4 +08a +0ff +976 +25f +618 +249 +22c +f28 +aa7 +e01 +fa8 +ad3 +22c +251 +fc8 +af3 +972 +f08 +976 +22c +614 +214 +251 +fc0 +614 +214 +e21 +22d +fc8 +ac8 +22d +e4a +e0a +2d9 +6bc +22d +fa0 +964 +024 +907 +000 +d55 +000 +255 +618 +214 +22d +fa8 +b61 +30b +62d +aad +972 +f08 +af5 +22d +962 +218 +6d0 +963 +000 +214 +62d +965 +974 +af3 +ada +ae3 +a90 +118 +963 +024 +255 +618 +61e +959 +964 +024 +a92 +62e +965 +968 +3f7 +aec +22e +e44 +236 +ae3 +972 +976 +881 +30b +967 +474 +c87 +972 +976 +881 +40b +b5e +0a0 +0ab +0ad +0af +0aa +0de +0a8 +0db +0bc +0a9 +0dd +0be +0ac +0bb +08d +0bd +963 +505 +964 +024 +299 +fc8 +929 +907 +e00 +c98 +000 +255 +618 +8a7 +b97 +392 +000 +000 +000 +000 +003 +000 +22c +251 +fc0 +b9d +22c +250 +fe0 +49d +b9d +000 +30b +62d +29c +30b +e21 +22c +fa0 +976 +965 +ba7 +000 +c02 +96d +bb2 +416 +965 +236 +24e +fa0 +ab7 +20f +e20 +213 +62f +25b +e21 +213 +fa8 +a7f +e00 +313 +715 +25b +639 +339 +f28 +ad7 +61a +213 +e61 +21a +f98 +22f +21a +739 +21a +ac9 +e20 +213 +609 +22f +e20 +213 +60a +22f +230 +630 +208 +e20 +20a +61a +208 +22f +608 +30a +709 +41a +ae8 +ab3 +000 +934 +636 +968 +393 +bed +969 +bed +55b +5a8 +59e +575 +598 +54f +57a +594 +595 +5ac +57d +5c2 +599 +577 +0d8 +974 +a9f +a92 +a8b +236 +24a +f20 +976 +25d +630 +75b +230 +619 +a7f +96c +230 +608 +975 +413 +235 +fc0 +313 +973 +a8f +313 +637 +a95 +230 +619 +b61 +000 +25b +615 +25b +613 +213 +609 +237 +e61 +309 +f28 +ab6 +f98 +ab7 +213 +615 +313 +f20 +aa6 +f08 +4a2 +213 +e01 +60f +610 +ba2 +000 +8d8 +fc8 +206 +2ef +236 +f28 +ace +23d +636 +216 +240 +fa8 +969 +bbc +8d8 +e20 +abe +216 +fa0 +ad6 +240 +fa8 +e01 +640 +abd +248 +ac5 +000 +410 +ae5 +211 +052 +636 +236 +243 +fa8 +acb +236 +2ee +bd8 +30f +611 +e20 +610 +211 +e4a +e0a +e0a +adc +fe0 +fa1 +000 +e00 +315 +730 +230 +715 +231 +f20 +708 +208 +e01 +630 +230 +619 +bf0 +2ab +18c +c82 +1ef +1ef +ca8 +001 +400 +000 +000 +000 +000 +ff6 +000 +c19 +a8d +c1e +046 +f28 +a8d +253 +b8c +000 +237 +96f +052 +8a2 +242 +969 +237 +8a2 +2ee +636 +969 +b95 +000 +046 +61a +24b +61b +aaa +41b +61a +21a +28b +f40 +aa8 +e80 +21b +969 +21a +24b +969 +ba2 +000 +f28 +236 +24e +f28 +abe +23f +933 +bb5 +23f +933 +23e +abc +000 +248 +e21 +236 +f28 +2ea +241 +f28 +bed +2eb +639 +239 +0ec +2ee +f20 +2ec +fa8 +ada +239 +052 +f20 +8dd +e00 +bc2 +252 +8dd +ad4 +000 +432 +aef +231 +708 +631 +20b +e61 +205 +208 +f90 +bdd +976 +020 +0ff +060 +604 +fa0 +96f +631 +e20 +632 +bdd +580 +080 +580 +080 +580 +080 +580 +080 +580 +080 +580 +080 +000 +000 +f7d +680 +e08 +681 +c21 +a95 +c22 +60e +3b5 +f28 +a95 +c24 +60e +7b5 +2b5 +e01 +047 +2b3 +6b5 +c19 +aa6 +c1e +046 +f28 +aa6 +253 +6b2 +2b2 +282 +fa8 +ae0 +21c +fa0 +976 +2b2 +61c +c09 +aaa +c0a +61f +ca4 +c41 +e00 +281 +e44 +280 +c01 +b00 +000 +650 +650 +650 +000 +21c +f68 +ab7 +6be +61c +2be +bb6 +000 +6b6 +c01 +3b4 +fa0 +ac1 +c02 +20e +fa0 +acc +2b6 +c26 +60e +ad3 +2b6 +7b4 +2b4 +e01 +047 +2b3 +6b4 +c01 +bbe +6d6 +000 +ea0 +2d6 +637 +c01 +20e +fa0 +adb +c02 +ae2 +253 +637 +40e +245 +62f +e20 +2b3 +608 +e00 +708 +42f +ae9 +61c +2b3 +6b5 +2b3 +6b4 +e20 +c26 +241 +969 +96b +412 +312 +f28 +aff +637 +241 +969 +969 +96b +23f +969 +256 +66a +a7f +232 +fa0 +a8c +208 +e21 +217 +fc0 +ba1 +2a9 +969 +208 +639 +e00 +432 +aa2 +339 +052 +243 +fa0 +a9f +e20 +632 +e20 +208 +608 +339 +041 +631 +ba1 +558 +339 +041 +206 +fa0 +a98 +739 +a99 +0dc +230 +618 +219 +e21 +218 +fa8 +b61 +318 +6ce +2cd +60f +610 +965 +969 +965 +969 +965 +969 +418 +318 +9cc +965 +969 +418 +907 +118 +000 +958 +23f +969 +238 +249 +218 +aab +522 +64d +000 +a29 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +0ed +18f +0c1 +32c +c79 +db9 +fcd +fff +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +5e1 +2f8 +67e +c62 +c3f +c6a +df2 +c0a +ce6 +dfa +ec0 +70c +42f +a83 +2f2 +8f9 +2f8 +600 +e20 +c77 +e80 +c79 +fa8 +a96 +2f5 +c61 +2f6 +c61 +e80 +ac8 +c61 +00f +002 +e01 +fa8 +ac6 +e41 +ce4 +cd9 +fc0 +aa6 +2e8 +7ea +2e9 +7eb +ac7 +eec +2f7 +fa8 +ab5 +ee4 +2f6 +fa8 +aca +240 +7f4 +28a +7f3 +acb +5f1 +acc +c26 +c00 +c00 +c00 +c00 +c00 +c00 +c00 +c00 +42f +c21 +ab6 +22f +258 +fc8 +ac9 +518 +518 +518 +518 +518 +518 +518 +c26 +c01 +960 +111 +c02 +2f0 +8f9 +f28 +ae4 +fc8 +2f6 +250 +62f +2ec +609 +2ed +709 +42f +adb +2f0 +8f9 +fc8 +244 +2ee +2ef +61d +be7 +48c +ccb +cc7 +26b +26e +101 +5d5 +170 +98f +606 +5b1 +404 +cd2 +5ac +007 +002 +802 +932 +4e4 +631 +960 +31f +418 +318 +bf9 +96e +ee6 +6f6 +280 +6f1 +380 +e48 +6f5 +e0a +6f4 +8a9 +2f1 +680 +d80 +e01 +8dd +225 +fc8 +9d4 +61b +907 +8cb +dbd +000 +92b +6d5 +907 +e00 +dbe +1bd +5be +dbd +9bd +dbe +2c8 +cd6 +0c5 +6d6 +5bd +2bf +cd6 +0c2 +9be +2d6 +cd6 +1bd +6d6 +8d1 +2ce +000 +2d5 +224 +624 +41b +b5e +907 +dbd +0ce +7bd +000 +b5e +ad2 +ad6 +004 +4fa +302 +ffc +46f +a6f +00a +b2c +0e3 +007 +576 +ae1 +001 +5c5 +51d +001 +400 +000 +002 +400 +000 +a73 +000 +000 +000 +000 +000 +907 +1bd +9bd +dbe +8fc +2f9 +9be +2f6 +cd6 +0f3 +9be +2f0 +9be +2ed +9bd +6d6 +000 +bec +a14 +000 +51f +3a3 +fff +6c4 +91c +ffb +6c6 +b2c +000 +51f +3a6 +000 +517 +4d3 +ffd +717 +e2a +003 +225 +fc8 +8f3 +61b +907 +d9d +59f +000 +225 +fc8 +a91 +907 +19f +79d +d9d +000 +ea0 +6f2 +b93 +9da +4f2 +b9c +907 +d9d +19e +59d +000 +b9c +ac2 +ad2 +ace +9ce +225 +f28 +976 +fc8 +929 +907 +dee +59f +000 +225 +f28 +b5e +fc0 +ab4 +907 +19f +7ee +dee +000 +ea0 +61b +205 +624 +e20 +3ee +625 +626 +627 +e01 +7ee +907 +8ef +d9d +1ee +59f +dee +8eb +2e8 +9ee +2e5 +9ee +2e2 +9ee +2df +9ee +2dc +9ee +2d9 +9ee +2d6 +9ee +39d +000 +b9c +000 +7ff +fe2 +fff +800 +840 +fff +54f +0c7 +ffe +84b +e89 +ffe +55d +6c1 +ffd +9e6 +1f9 +ffc +49e +8c4 +ff9 +964 +3dd +9d6 +000 +58b +90c +000 +000 +929 +ea0 +bf3 +24e +585 +494 +000 +0d6 +158 +0c5 +414 +000 +907 +cd2 +0ce +4d2 +000 +225 +fe0 +a8d +225 +fc0 +b5e +929 +e20 +61b +907 +6c6 +cd6 +000 +92b +907 +e00 +cd2 +0d6 +4d2 +8c6 +cd2 +4ca +000 +225 +fc8 +aa5 +907 +cd2 +000 +21b +e20 +61b +907 +0d2 +4ce +000 +225 +fc8 +ab1 +907 +0ca +4d2 +cd2 +000 +907 +0d2 +6ce +cd2 +8d2 +cd6 +0da +8d6 +2de +8d6 +2e2 +8d6 +2e6 +8d6 +2ce +8d2 +000 +41b +b5e +929 +b5e +003 +648 +7ee +69d +002 +648 +7ee +69d +001 +648 +7ee +69d +000 +000 +000 +000 +000 +000 +000 +000 +ff4 +501 +e0d +222 +ff9 +b34 +b4c +c68 +ffd +519 +af1 +9de +000 +ad5 +10c +677 +414 +000 +0d6 +585 +493 +24f +000 +0d7 +580 +0d6 +0cf +315 +34e +000 +0da +4d0 +043 +153 +000 +0c2 +412 +144 +000 +6dc +22a +96f +052 +61a +21a +e21 +f28 +2d6 +6dd +22a +f28 +aa1 +052 +6db +2dd +2db +f48 +a98 +ea0 +21a +6db +e20 +21b +f40 +e80 +21a +f48 +ab3 +2d6 +f40 +e80 +2d7 +639 +3d9 +239 +6de +239 +e21 +639 +2d5 +5de +3de +2d8 +fc8 +ab5 +7de +439 +ad1 +5de +41b +e80 +22a +fa8 +aee +2dd +21b +f60 +aed +2db +f40 +e80 +e21 +21b +e21 +61a +21b +21a +fa8 +ae3 +21a +e01 +fc8 +245 +8de +41a +ac3 +242 +969 +ac3 +e20 +2de +6de +aaa +005 +ffa +007 +ff6 +c68 +c6c +000 +000 +000 +000 +9da +4dd +bde +b80 +e20 +21b +61b +4dc +aeb +e20 +6dc +acb +30c +acb +e80 +9da +242 +969 +480 +30c +8de +4dc +af2 +e20 +6dc +af3 +000 +225 +628 +225 +fc8 +929 +bf9 +000 +626 +624 +625 +627 +6cc +628 +236 +2b4 +f28 +a90 +249 +fa0 +a91 +e20 +628 +9b6 +236 +2b5 +fa8 +a90 +897 +b80 +000 +236 +2b2 +fa8 +b97 +971 +b97 +aa7 +22c +6cb +8b7 +4cc +fa0 +976 +9b6 +a98 +236 +24a +fc8 +b97 +236 +2b3 +fe0 +b97 +236 +052 +aa0 +f3b +f26 +f55 +f60 +1ee +000 +227 +623 +226 +622 +225 +621 +6ca +8cd +8cd +8db +8cd +2cb +623 +622 +621 +8db +2ca +bb7 +000 +000 +000 +000 +227 +e44 +627 +226 +e04 +626 +225 +e04 +625 +2ca +e04 +6ca +bcd +000 +ec0 +227 +223 +627 +e04 +226 +222 +626 +e04 +225 +221 +625 +e04 +2ca +6ca +bdb +000 +ec0 +221 +f48 +e50 +e08 +621 +222 +e08 +622 +223 +e08 +623 +420 +bec +bec +0c1 +484 +4c0 +0c3 +000 +2dd +969 +225 +fc0 +2dc +2de +969 +9eb +61b +224 +f48 +a97 +f20 +2e1 +fe8 +a9c +907 +9e4 +000 +e01 +21b +a89 +907 +9ea +000 +e20 +a95 +7e5 +7e6 +2e8 +60c +224 +e60 +6ec +2e3 +624 +957 +4ec +aa5 +3e6 +f28 +ab8 +2e2 +fc8 +ab4 +e01 +70c +424 +2e2 +41b +e00 +3e6 +41b +e00 +f08 +9e7 +70c +424 +ab8 +2e8 +60c +2e3 +9e9 +b80 +2db +969 +21b +f48 +e21 +625 +21b +fc0 +249 +2de +969 +225 +424 +2df +f40 +acd +2e0 +625 +e20 +224 +f20 +8ec +225 +9da +b80 +522 +0c5 +ff3 +0bd +0ad +f9c +064 +ffc +ff6 +ff9 +cbd +bcb +bca +bb7 +f37 +b00 +cb9 +b79 +000 +24b +969 +bec +d5f +d62 +d65 +d6d +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +fa0 +9c6 +236 +24c +fa8 +a82 +9c2 +236 +24d +fa0 +a91 +9c6 +7c5 +9c3 +3c5 +e21 +61b +2c8 +624 +9c4 +9c7 +907 +d18 +000 +236 +2c1 +fa0 +aa6 +9c6 +9c2 +9c4 +227 +21b +61b +907 +118 +000 +21b +f28 +b80 +fc0 +ab1 +907 +8bd +d18 +000 +e01 +ab6 +907 +8b9 +d18 +000 +e20 +21b +61b +aa6 +004 +500 +000 +000 +ffd +666 +667 +668 +f3b +b80 +b97 +e7b +bcc +1ee +edd +023 +ed9 +aa4 +e12 +000 +92f +000 +801 +d80 +000 +245 +6e3 +21f +fc0 +af4 +41a +ad4 +4e3 +ad4 +8e3 +20b +2fe +f90 +be2 +40b +b61 +08a +000 +2fd +e20 +6fd +e60 +61f +2fd +f20 +c0c +fa0 +2ff +256 +66a +be3 +8e3 +bf3 +189 +e20 +61f +c0e +046 +f28 +ad2 +253 +636 +bd1 +000 +96f +864 +000 +ec0 +627 +623 +380 +f28 +b80 +6b2 +2b2 +053 +fa8 +a8e +244 +080 +620 +246 +0b2 +220 +620 +2b3 +0b2 +fa8 +a99 +320 +620 +480 +e20 +220 +60d +2b2 +e46 +e06 +047 +f28 +ab7 +2b4 +6b2 +3b2 +f28 +ab5 +6b2 +2c4 +60c +24f +62f +30d +70c +42f +aad +bb2 +000 +100 +d7b +2c3 +abb +2c3 +60d +e20 +220 +60c +24f +62f +30c +70d +42f +abe +a81 +023 +01f +9f5 +9f8 +a81 +9fa +9f9 +9fb +9f7 +a81 +225 +fa0 +ad5 +624 +625 +626 +627 +a81 +963 +024 +963 +020 +964 +024 +92b +f48 +ae2 +e20 +6b2 +623 +225 +fa0 +976 +963 +505 +964 +024 +964 +f38 +af0 +963 +f38 +964 +020 +9f6 +4b2 +aeb +a81 +9f6 +a81 +e6b +e04 +edd +d93 +bec +def +bdb +d46 +d45 +e47 +d73 +d4d +000 +d4b +000 +ec0 +227 +e21 +627 +226 +e20 +f18 +e41 +626 +225 +e20 +f18 +e41 +625 +b83 +000 +225 +f28 +226 +fa8 +ac9 +221 +f28 +222 +f28 +223 +fa8 +b93 +220 +e21 +224 +f28 +abb +683 +283 +f40 +e21 +6d2 +2d2 +2de +fc8 +abd +283 +fc0 +ab5 +8ef +4d2 +ab1 +abb +e20 +220 +620 +9d3 +4d2 +ab8 +493 +b93 +220 +fc0 +ac4 +224 +fc0 +b93 +ac6 +224 +fc0 +283 +fe0 +b93 +220 +624 +221 +625 +222 +626 +223 +627 +b93 +000 +bec +000 +9e9 +224 +fe8 +aeb +e01 +623 +2e8 +620 +893 +017 +427 +ae4 +426 +f08 +425 +627 +9ea +226 +bd4 +017 +b79 +e7b +624 +625 +626 +ae4 +000 +ec0 +225 +f48 +e10 +e08 +625 +226 +e08 +626 +227 +e08 +627 +424 +bef +bef +0df +0ff +08a +0fd +fff +000 +e01 +220 +8d4 +fc8 +8eb +6c1 +6c0 +6bf +6be +225 +7e9 +221 +9ea +002 +222 +9ea +003 +226 +7e9 +221 +9ea +003 +222 +9ea +004 +ab3 +6bc +223 +7e9 +225 +9ea +004 +226 +9ea +005 +227 +7e9 +221 +9ea +004 +222 +9ea +005 +223 +9ea +006 +2c1 +625 +2c0 +626 +2bf +627 +8c1 +627 +b84 +ab7 +c26 +c16 +db6 +000 +000 +428 +929 +9e7 +427 +bc1 +221 +fa8 +976 +220 +e21 +e01 +8d4 +fc0 +8eb +9e8 +8c1 +bd3 +d01 +000 +224 +624 +254 +025 +221 +fc0 +e20 +628 +225 +f28 +be6 +fc8 +929 +221 +f28 +be6 +bd4 +d50 +edd +eb1 +eae +e80 +000 +ec0 +223 +e21 +623 +222 +e20 +f18 +e41 +622 +221 +e20 +f18 +e41 +621 +beb +000 +228 +fc8 +929 +bfb +000 +f28 +b80 +6ac +6ab +2af +6ad +e40 +2ac +e08 +6ac +2ab +f10 +a90 +e40 +2ae +e08 +6ab +4ad +a88 +2ac +e08 +6ad +380 +e21 +2aa +6ac +2ad +e40 +3ac +7ac +4ac +e04 +2ab +3ac +7ac +f10 +b80 +4ac +5ac +b80 +aa6 +e42 +000 +000 +000 +000 +ff4 +fe9 +000 +680 +6ac +2b0 +6ad +f08 +957 +e40 +222 +226 +6ae +e04 +225 +221 +f10 +ac4 +625 +2ae +626 +e80 +2ac +e04 +6ac +280 +e04 +680 +4ad +ab7 +2ac +626 +280 +625 +bb1 +e04 +6dd +4ad +ab7 +2dd +625 +280 +626 +2ac +627 +bb1 +000 +9fd +8f6 +225 +f28 +227 +f28 +226 +fa8 +af3 +225 +e44 +fc8 +af0 +957 +e60 +224 +624 +ae7 +9fe +8f6 +bdd +624 +bdd +def +000 +225 +f48 +e21 +fc8 +9f5 +bf6 +b79 +e7b +9f2 +907 +cbc +000 +225 +fc8 +976 +224 +f48 +e10 +e08 +6b8 +f18 +4b8 +e00 +2b7 +6b9 +6ba +6bb +2bd +f28 +2be +fa8 +ab5 +907 +0bc +6b8 +2b8 +000 +ea0 +224 +624 +224 +e21 +2b8 +fa0 +ab1 +225 +e21 +2b9 +fa0 +ab1 +226 +e21 +2ba +f40 +e21 +e01 +fc0 +b5e +907 +cb8 +000 +a97 +624 +b5e +60d +000 +000 +000 +000 +000 +000 +000 +f43 +e06 +e04 +6e4 +25b +8d7 +230 +8d7 +219 +8d7 +21d +8d7 +ace +965 +969 +236 +24e +fa0 +acc +20e +fa0 +ad2 +c02 +b44 +000 +61a +21a +e06 +e06 +8e8 +96f +e04 +8e8 +e0a +e08 +8e8 +8e8 +e80 +23f +969 +bd7 +000 +0ee +24b +969 +21a +be8 +007 +0af +f3a +e82 +e91 +e95 +e60 +e5d +e34 +e9e +ed7 +e7e +edd +f45 +f0e +f5e +f5d +e6a +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +000 +c81 +080 +78a +f80 +28a +f02 +f02 +f02 +f02 +f02 +f02 +fd5 +68a +8b0 +2c0 +fe8 +a9f +48a +e20 +a97 +28a +fa0 +a98 +28c +0bc +2e1 +f48 +496 +fe8 +b96 +28c +0ae +2af +68b +a98 +038 +c81 +f99 +ab8 +c19 +ab2 +c1e +68c +28c +bb0 +c09 +ab8 +c0e +ab5 +0c0 +8e3 +e21 +28d +f02 +c1a +c0c +c8c +2af +68b +f84 +fc0 +2eb +2ea +6b1 +896 +acb +68d +28b +6de +28c +6fe +8b0 +6ed +896 +abd +8e3 +f10 +ade +68e +2fe +2ed +28d +acd +c81 +78e +48e +f80 +ada +fbe +2fe +e46 +e06 +e06 +2ed +be3 +ab2 +006 +000 +00a +c0c +c09 +aef +c0e +e46 +e06 +f48 +afc +e06 +c09 +af7 +c0e +f10 +7fe +6fe +aef +01e +ac1 diff --git a/mem/hello.pal b/mem/hello.pal new file mode 100644 index 0000000..89383ba --- /dev/null +++ b/mem/hello.pal @@ -0,0 +1,45 @@ + *001 + JMP I (INT) + *200 +START, ION + CLA CLL + TAD HELLO + DCA Z 10 +LOOP, TAD I Z 10 + SNA + JMP ECHO + TLS + TSF + JMP .-1 + CLA + JMP LOOP +ECHO, CLA + TAD (1) + KIE + JMP . +HELLO, . + "H + "e + "l + "l + "o + ", + " + "w + "o + "r + "l + "d + "! + 15 + 12 + 0 + *300 +INT, KRB + TLS + TSF + JMP .-1 + RMF + ION + JMP I Z 000 +$ diff --git a/tcl/clean.tcl b/tcl/clean.tcl new file mode 100644 index 0000000..13c3bd4 --- /dev/null +++ b/tcl/clean.tcl @@ -0,0 +1,3 @@ +project_open pdp8 -revision pdp8 + +project_clean -revision pdp8 diff --git a/tcl/init.tcl b/tcl/init.tcl new file mode 100644 index 0000000..8665ee9 --- /dev/null +++ b/tcl/init.tcl @@ -0,0 +1,107 @@ +project_new pdp8 -revision pdp8 -overwrite + +set_global_assignment -name DEVICE 10CL025YU256I7G + +set_global_assignment -name TOP_LEVEL_ENTITY top +set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 +set_global_assignment -name VERILOG_MACRO "SYNTHESIS=1" +set_global_assignment -name NUM_PARALLEL_PROCESSORS 1 +set_global_assignment -name ENABLE_SIGNALTAP OFF + +proc pin {net loc} { + set_location_assignment -to $net "PIN_$loc" + set_instance_assignment -name IO_STANDARD "3.3V LVTTL" -to $net +} + +proc iopin {net loc} { + pin $net $loc + set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to $net +} + +proc rampin {net loc} { + set_location_assignment -to $net "PIN_$loc" + set_instance_assignment -name IO_STANDARD "1.8V" -to $net +} + +pin clock E1 + +iopin resetn J15 + +iopin gpioa[1] L13 +iopin gpioa[2] L16 +iopin gpioa[3] L15 +iopin gpioa[4] K16 +iopin gpioa[5] P16 +iopin gpioa[6] R16 +iopin gpioa[7] N16 +iopin gpioa[8] N15 +iopin gpioa[9] N14 +iopin gpioa[10] P15 +iopin gpiob[13] N8 +iopin gpiob[14] P8 +iopin gpiob[15] M8 +iopin gpiob[16] L8 +iopin gpiob[17] R7 +iopin gpiob[18] T7 +iopin gpiob[19] L7 +iopin gpiob[20] M7 +iopin gpiob[21] R6 +iopin gpiob[22] T6 +iopin gpiob[23] T2 +iopin gpiob[24] M6 +iopin gpiob[25] R5 +iopin gpiob[26] T5 +iopin gpiob[27] N5 +iopin gpiob[28] N6 +iopin gpioc[31] R4 +iopin gpioc[32] T4 +iopin gpioc[33] N3 +iopin gpioc[34] P3 +iopin gpioc[35] R3 +iopin gpioc[36] T3 +iopin gpioc[37] P6 +iopin gpioc[38] P2 +iopin gpioc[39] P1 +iopin gpioc[40] R1 + +rampin ram_data[0] T12 +rampin ram_data[1] T13 +rampin ram_data[2] T11 +rampin ram_data[3] R10 +rampin ram_data[4] T10 +rampin ram_data[5] R11 +rampin ram_data[6] R12 +rampin ram_data[7] R13 +rampin ram_csn P9 +rampin ram_rwds T14 +rampin ram_clkp P14 +rampin ram_clkn R14 +rampin ram_resetn N9 + +# This is the clock for timing-driven synthesis, not timing analysis. +# See clocks.sdf for the other clock. +create_base_clock -fmax "50 MHz" clock + +proc add_files {typ ext dir} { + foreach name [glob -nocomplain -directory $dir -type f "*.$ext"] { + set_global_assignment -name "${typ}_FILE" $name + } +} + +proc add_dir {dir} { + add_files CDF cdf $dir + add_files HEX hex $dir + add_files SDC sdc $dir + add_files USE_SIGNALTAP stp $dir + add_files SIGNALTAP stp $dir + add_files VERILOG sv $dir + add_files VERILOG svh $dir + + foreach subdir [glob -nocomplain -directory $dir -type d *] { + add_dir $subdir + } +} + +add_dir . + +project_close -- cgit v1.2.3