gateware

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 76056d1ce0d78e2b809674e57450beac991483fc
parent c9e3b82f6032a6b563e5ca71af9825d6604a9630
Author: Brian Swetland <swetland@frotz.net>
Date:   Wed,  5 Feb 2020 05:09:21 -0800

sdram: progressing

- discard astl and old test infrastructure
- tidied up sdram/testbecnh.sv into sdram/memtest1.sv
- pulled sdram module instantiation outsode of memtest1 module
- added tunables for clock delay in sdram_glue_scp5.sv
- memtest1 passes on colorlight board w/ EM636165
- memtest1 passes on ulx3s board w/ AS4C32M16SB
- project and constraints for ulx3s
- temporarily broke test-sram-vsim (gotta do something about
  verilator and tristate outputs...)

Diffstat:
MMakefile | 7-------
Mhdl/colorlight-sdram.sv | 86++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Ahdl/lattice/ecp5_pll_25_100.v | 48++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/sdram/memtest1.sv | 240+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mhdl/sdram/sdram.sv | 23+++++++++++++----------
Mhdl/sdram/sdram_glue_ecp5.sv | 22+++++++++++++++++-----
Dhdl/sdram/test.asm | 61-------------------------------------------------------------
Dhdl/sdram/testbench.sv | 287-------------------------------------------------------------------------------
Ahdl/ulx3s-sdram.sv | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/ulx3s.lpf | 462+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mproject/colorlight-sdram.def | 2+-
Aproject/ulx3s-sdram.def | 9+++++++++
Dsrc/astl.c | 112-------------------------------------------------------------------------------
13 files changed, 982 insertions(+), 497 deletions(-)

diff --git a/Makefile b/Makefile @@ -32,13 +32,6 @@ list-all-targets:: #### Tools #### -out/astl: src/astl.c - @mkdir -p out - gcc -g -Wall -O1 -o out/astl src/astl.c - -hdl/sdram/test.hex: hdl/sdram/test.asm out/astl - ./out/astl < hdl/sdram/test.asm > hdl/sdram/test.hex - out/a16: src/a16v5.c src/d16v5.c @mkdir -p out gcc -g -Wall -O1 -o out/a16 src/a16v5.c src/d16v5.c diff --git a/hdl/colorlight-sdram.sv b/hdl/colorlight-sdram.sv @@ -28,6 +28,7 @@ module top( wire clk25m = phy_clk; +`define CLK125 `ifdef CLK125 wire clk125m; wire clk250m; @@ -48,33 +49,90 @@ pll_25_100 pll( ); `endif -wire testclk = clk100m; +wire testclk = clk125m; + +wire [19:0]rd_addr; +wire [15:0]rd_data; +wire [3:0]rd_len; +wire rd_req; +wire rd_ack; +wire rd_rdy; + +wire [19:0]wr_addr; +wire [15:0]wr_data; +wire wr_req; +wire wr_ack; +wire [3:0]wr_len; wire [15:0]info; wire info_e; testbench #( - .T_PWR_UP(25000), - .T_RI(1900) + .BANKBITS(1), + .ROWBITS(11), + .COLBITS(8) ) test0 ( .clk(testclk), .error(), .done(), - .sdram_clk(sdram_clk), - .sdram_ras_n(sdram_ras_n), - .sdram_cas_n(sdram_cas_n), - .sdram_we_n(sdram_we_n), - .sdram_addr(sdram_addr), -`ifdef verilator - .sdram_data_i(sdram_data), - .sdram_data_o(), -`else - .sdram_data(sdram_data), -`endif + + .rd_addr(rd_addr), + .rd_data(rd_data), + .rd_len(rd_len), + .rd_req(rd_req), + .rd_ack(rd_ack), + .rd_rdy(rd_rdy), + + .wr_addr(wr_addr), + .wr_data(wr_data), + .wr_len(wr_len), + .wr_req(wr_req), + .wr_ack(wr_ack), + .info(info), .info_e(info_e) ); +sdram #( + .BANKBITS(1), + .ROWBITS(11), + .COLBITS(8), + .T_PWR_UP(25000), + .T_RI(1900), + .T_RCD(3), + .CLK_SHIFT(1), + .CLK_DELAY(0) + ) sdram0 ( + .clk(testclk), + .reset(0), + + .pin_clk(sdram_clk), + .pin_ras_n(sdram_ras_n), + .pin_cas_n(sdram_cas_n), + .pin_we_n(sdram_we_n), + .pin_addr(sdram_addr), + .pin_data(sdram_data), + +`ifdef SWIZZLE + .rd_addr({rd_addr[7:4],rd_addr[19:8],rd_addr[3:0]}), + .wr_addr({wr_addr[7:4],wr_addr[19:8],wr_addr[3:0]}), +`else + .rd_addr(rd_addr), + .wr_addr(wr_addr), +`endif + + .rd_data(rd_data), + .rd_len(rd_len), + .rd_req(rd_req), + .rd_ack(rd_ack), + .rd_rdy(rd_rdy), + + .wr_data(wr_data), + .wr_len(wr_len), + .wr_req(wr_req), + .wr_ack(wr_ack) +); + assign j1r1 = j1r0; assign j1b1 = j1b0; diff --git a/hdl/lattice/ecp5_pll_25_100.v b/hdl/lattice/ecp5_pll_25_100.v @@ -0,0 +1,48 @@ +// diamond 3.7 accepts this PLL +// diamond 3.8-3.9 is untested +// diamond 3.10 or higher is likely to abort with error about unable to use feedback signal +// cause of this could be from wrong CPHASE/FPHASE parameters +module pll_25_100 +( + input clk25m_in, // 25 MHz, 0 deg + output clk100m_out, // 100 MHz, 0 deg + output locked +); +`ifndef verilator +(* FREQUENCY_PIN_CLKI="25" *) +(* FREQUENCY_PIN_CLKOP="100" *) +(* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *) +EHXPLLL #( + .PLLRST_ENA("DISABLED"), + .INTFB_WAKE("DISABLED"), + .STDBY_ENABLE("DISABLED"), + .DPHASE_SOURCE("DISABLED"), + .OUTDIVIDER_MUXA("DIVA"), + .OUTDIVIDER_MUXB("DIVB"), + .OUTDIVIDER_MUXC("DIVC"), + .OUTDIVIDER_MUXD("DIVD"), + .CLKI_DIV(1), + .CLKOP_ENABLE("ENABLED"), + .CLKOP_DIV(6), + .CLKOP_CPHASE(2), + .CLKOP_FPHASE(0), + .FEEDBK_PATH("CLKOP"), + .CLKFB_DIV(4) + ) pll_i ( + .RST(1'b0), + .STDBY(1'b0), + .CLKI(clk25m_in), + .CLKOP(clk100m_out), + .CLKFB(clk100m_out), + .CLKINTFB(), + .PHASESEL0(1'b0), + .PHASESEL1(1'b0), + .PHASEDIR(1'b1), + .PHASESTEP(1'b1), + .PHASELOADREG(1'b1), + .PLLWAKESYNC(1'b0), + .ENCLKOP(1'b0), + .LOCK(locked) + ); +`endif +endmodule diff --git a/hdl/sdram/memtest1.sv b/hdl/sdram/memtest1.sv @@ -0,0 +1,240 @@ +// Copyright 2020, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. + +`default_nettype none + +module testbench #( + parameter BANKBITS = 1, + parameter ROWBITS = 11, + parameter COLBITS = 8, + parameter DWIDTH = 16 + ) ( + input clk, + output reg error = 0, + output reg done = 0, + + output reg [XWIDTH-1:0]rd_addr = 0, + output reg [3:0]rd_len = 0, + output reg rd_req = 0, + input wire rd_ack, + input wire [DWIDTH-1:0]rd_data, + input wire rd_rdy, + + output reg [XWIDTH-1:0]wr_addr = 0, + output reg [DWIDTH-1:0]wr_data = 0, + output reg [3:0]wr_len = 0, + output reg wr_req = 0, + input wire wr_ack, + + output reg [15:0]info = 0, + output reg info_e = 0 +); + +localparam AWIDTH = (ROWBITS + BANKBITS); +localparam XWIDTH = (ROWBITS + BANKBITS + COLBITS); + +localparam AMSB = XWIDTH-1; +localparam DMSB = DWIDTH-1; + +reg [15:0]info_next; +reg info_e_next; + +reg [AMSB:0]rd_addr_next; +reg [3:0]rd_len_next; +reg rd_req_next; + +reg [AMSB:0]wr_addr_next; +reg [DMSB:0]wr_data_next; +reg [3:0]wr_len_next; +reg wr_req_next; + +reg [31:0]pattern0; +reg pattern0_reset = 0; +reg pattern0_reset_next; +reg pattern0_step = 0; +reg pattern0_step_next; + +reg [31:0]pattern1; +reg pattern1_reset = 0; +reg pattern1_reset_next; +reg pattern1_step = 0; +reg pattern1_step_next; + +reg [16:0]count = 17'd30000; +reg [16:0]count_next; +wire count_done = count[16]; +wire [16:0]count_minus_one = count - 17'd1; + +localparam START = 3'd0; +localparam START2 = 3'd1; +localparam WRITE = 3'd2; +localparam READ = 3'd3; +localparam HALT = 3'd4; + +reg [2:0]state = START; +reg [2:0]state_next; + +localparam BLOCK = 17'd1023; + +`define READX16 + +reg [DMSB:0]chk_ptn = 0; +reg [DMSB:0]chk_ptn_next; +reg [DMSB:0]chk_dat = 0; +reg [DMSB:0]chk_dat_next; +reg chk = 0; +reg chk_next; + +reg error_next; + +reg [20:0]colormap = 21'b111110101100011010001; +reg [20:0]colormap_next; + +always_comb begin + state_next = state; + error_next = error; + count_next = count; + rd_addr_next = rd_addr; + rd_req_next = rd_req; + rd_len_next = rd_len; + wr_addr_next = wr_addr; + wr_data_next = wr_data; + wr_req_next = wr_req; + wr_len_next = wr_len; + pattern0_reset_next = 0; + pattern1_reset_next = 0; + pattern0_step_next = 0; + pattern1_step_next = 0; + colormap_next = colormap; + info_next = info; + info_e_next = 0; + + chk_ptn_next = chk_ptn; + chk_dat_next = chk_dat; + chk_next = 0; + + // verify pipeline 1: capture read data and pattern + if (rd_rdy) begin + chk_ptn_next = pattern1[DMSB:0]; + chk_dat_next = rd_data; + chk_next = 1; + pattern1_step_next = 1; + end + + // verify pipeline 2: compare and flag errors + if (chk) begin + error_next = (chk_ptn != chk_dat); + end + + case (state) + START: if (count_done) begin + state_next = START2; + info_e_next = 1; + info_next = { 1'b0, colormap[2:0], 4'h0, 6'h0, rd_addr[19:18] }; + end else begin + count_next = count_minus_one; + end + START2: begin + info_e_next = 1; + info_next = { 1'b0, colormap[2:0], 4'h0, rd_addr[17:10] }; + state_next = WRITE; + count_next = BLOCK; + colormap_next = { colormap[2:0], colormap[20:3] }; + end + WRITE: if (count_done) begin + state_next = READ; +`ifdef READX16 + count_next = 63; +`else + count_next = BLOCK; +`endif + end else begin + if (wr_req) begin + if (wr_ack) begin + wr_req_next = 0; + wr_addr_next = wr_addr + 1; + pattern0_step_next = 1; + count_next = count_minus_one; + end + end else begin + wr_req_next = 1; + wr_data_next = pattern0[DMSB:0]; + end + end + READ: if (count_done) begin + //info_e_next = 1; + //info_next = 16'h72CC; + state_next = START; + count_next = BLOCK; + end else begin + if (rd_req) begin + if (rd_ack) begin + rd_req_next = 0; +`ifdef READX16 + rd_addr_next = rd_addr + 16; +`else + rd_addr_next = rd_addr + 1; +`endif + count_next = count_minus_one; + end + end else begin + rd_req_next = 1; +`ifdef READX16 + rd_len_next = 15; +`endif + end + end + HALT: state_next = HALT; + default: state_next = HALT; + endcase + + if (error) begin + state_next = HALT; + info_next = { 16'h40EE }; + info_e_next = 1; + error_next = 0; + rd_req_next = 0; + wr_req_next = 0; + end +end + +reg reset = 1; + +always_ff @(posedge clk) begin + reset <= 0; + state <= state_next; + count <= count_next; + rd_addr <= rd_addr_next; + rd_req <= rd_req_next; + rd_len <= rd_len_next; + wr_addr <= wr_addr_next; + wr_data <= wr_data_next; + wr_req <= wr_req_next; + wr_len <= wr_len_next; + pattern0_reset <= pattern0_reset_next; + pattern1_reset <= pattern1_reset_next; + pattern0_step <= pattern0_step_next; + pattern1_step <= pattern1_step_next; + info <= info_next; + info_e <= info_e_next; + chk <= chk_next; + chk_dat <= chk_dat_next; + chk_ptn <= chk_ptn_next; + error <= error_next; + colormap <= colormap_next; +end + +xorshift32 xs0( + .clk(clk), + .next(pattern0_step_next), + .reset(pattern0_reset), + .data(pattern0) +); +xorshift32 xs1( + .clk(clk), + .next(pattern1_step_next), + .reset(pattern1_reset), + .data(pattern1) +); + +endmodule diff --git a/hdl/sdram/sdram.sv b/hdl/sdram/sdram.sv @@ -35,7 +35,11 @@ module sdram #( parameter T_RP = 3, // Precharge to Refresh/Activate parameter T_WR = 2, // Write Recovery TimeA parameter T_MRD = 3, // Mode Register Delay - parameter T_PWR_UP = 25000 // Power on delay + parameter T_PWR_UP = 25000, // Power on delay + + // Fine TuningA + parameter CLK_SHIFT = 0, // 1 = delay clock by 1/2 cycle (if 1) + parameter CLK_DELAY = 0 // 1..128 = delay clock by N x 25pS (ECP5) ) ( input wire clk, input wire reset, @@ -43,12 +47,7 @@ module sdram #( output wire pin_ras_n, output wire pin_cas_n, output wire pin_we_n, -`ifdef verilator - input wire [DWIDTH-1:0]pin_data_i, - output wire [DWIDTH-1:0]pin_data_o, -`else inout wire [DWIDTH-1:0]pin_data, -`endif output wire [AWIDTH-1:0]pin_addr, input wire [XWIDTH-1:0]rd_addr, @@ -406,7 +405,7 @@ end assign { ras_n, cas_n, we_n } = cmd; -wire [(ROWBITS-COLBITS)-1:0]io_misc = {{(ROWBITS-COLBITS)-1{1'b0}}, io_sel_a10 } << (10 - COLBITS); +wire [(ROWBITS-COLBITS)-1:0]io_misc = {{ROWBITS-10-1{1'b0}}, io_sel_a10, {10-COLBITS{1'b0}}}; wire [ROWBITS-1:0]io_low = io_sel_row ? io_row : { io_misc, io_col }; assign addr = { io_bank, io_low }; @@ -416,13 +415,17 @@ assign pin_ras_n = ras_n; assign pin_cas_n = cas_n; assign pin_we_n = we_n; assign pin_addr = addr; -assign pin_data_o = data_o; -assign data_i = pin_data_i; + +// TODO: fix me +assign pin_data = data_o; +assign data_i = pin_data; `else sdram_glue #( .AWIDTH(AWIDTH), - .DWIDTH(DWIDTH) + .DWIDTH(DWIDTH), + .CLK_SHIFT(CLK_SHIFT), + .CLK_DELAY(CLK_DELAY) ) glue ( .clk(clk), .pin_clk(pin_clk), diff --git a/hdl/sdram/sdram_glue_ecp5.sv b/hdl/sdram/sdram_glue_ecp5.sv @@ -5,7 +5,9 @@ module sdram_glue #( parameter AWIDTH = 12, - parameter DWIDTH = 16 + parameter DWIDTH = 16, + parameter CLK_DELAY = 0, // delay clock by 1..128 x 25pS + parameter CLK_SHIFT = 0 // delay clock by 1/2 cycle ) ( input wire clk, output wire pin_clk, @@ -28,12 +30,22 @@ assign pin_cas_n = cas_n; assign pin_we_n = we_n; assign pin_addr = addr; +wire delay_clk; + +DELAYG #( + .DEL_MODE("USER_DEFINED"), + .DEL_VALUE(CLK_DELAY) + ) clock_delay ( + .A(delay_clk), + .Z(pin_clk) +); + ODDRX1F clock_ddr ( - .Q(pin_clk), + .Q(delay_clk), .SCLK(clk), .RST(0), - .D0(1), - .D1(0) + .D0(CLK_SHIFT ? 0 : 1), + .D1(CLK_SHIFT ? 1 : 0) ); genvar n; @@ -49,4 +61,4 @@ end endgenerate endmodule - + diff --git a/hdl/sdram/test.asm b/hdl/sdram/test.asm @@ -1,61 +0,0 @@ -show aa -show bb -wait .25000 -show cc -addr 10 -wri 1234 -addr 20 -wri aa55 -addr 10 -rdc 1234 -addr 20 -rdc aa55 - -#trigger -auto+ -addr 80 -wrp 100 -show 42 - -p1rst -addr 80 -rdp 100 -show 43 - -show e0 -p1rst - -#trigger -addr f0 -wri 8888 - -addr 80 -show e1 -rdf 100 -show e2 -wait .30 -verify 100 -show e3 - -show ff - -show 00 -show 00 -#dump .250 - -p1rst -addr 80 -show bb -rdb .15 -wait .30 -verify .15 -show b0 - -addr 1000 -p0rst -#wrp ffff - -addr 1000 -p1rst -#rdp ffff -show a7 diff --git a/hdl/sdram/testbench.sv b/hdl/sdram/testbench.sv @@ -1,287 +0,0 @@ -// Copyright 2020, Brian Swetland <swetland@frotz.net> -// Licensed under the Apache License, Version 2.0. - -`default_nettype none - -module testbench #( - parameter T_PWR_UP = 3, - parameter T_RI = 32 - ) ( - input clk, - output reg error = 0, - output reg done = 0, - - output wire sdram_clk, - output wire sdram_ras_n, - output wire sdram_cas_n, - output wire sdram_we_n, - output wire [11:0]sdram_addr, -`ifdef verilator - input wire [15:0]sdram_data_i, - output wire [15:0]sdram_data_o, -`else - inout wire [15:0]sdram_data, -`endif - output reg [15:0]info = 0, - output reg info_e = 0 -); - - -reg [15:0]info_next; -reg info_e_next; - -reg [3:0]rd_len = 0; -reg rd_req = 0; -wire rd_ack; -wire [15:0]rd_data; -wire rd_rdy; - -reg [3:0]wr_len = 0; -reg wr_req = 0; -wire wr_ack; - -reg rd_req_next; -reg wr_req_next; -reg [3:0]rd_len_next; -reg [3:0]wr_len_next; - -localparam AMSB = 19; -localparam DMSB = 15; - -reg [AMSB:0]rd_addr = 0; -reg [AMSB:0]wr_addr = 0; -reg [DMSB:0]wr_data = 0; -reg [AMSB:0]rd_addr_next; -reg [AMSB:0]wr_addr_next; -reg [DMSB:0]wr_data_next; - -reg [31:0]pattern0; -reg pattern0_reset = 0; -reg pattern0_reset_next; -reg pattern0_step = 0; -reg pattern0_step_next; - -reg [31:0]pattern1; -reg pattern1_reset = 0; -reg pattern1_reset_next; -reg pattern1_step = 0; -reg pattern1_step_next; - -reg [16:0]count = 17'd30000; -reg [16:0]count_next; -wire count_done = count[16]; -wire [16:0]count_minus_one = count - 17'd1; - -localparam START = 3'd0; -localparam START2 = 3'd1; -localparam WRITE = 3'd2; -localparam READ = 3'd3; -localparam HALT = 3'd4; - -reg [2:0]state = START; -reg [2:0]state_next; - -localparam BLOCK = 17'd1023; - -`define READX16 - -reg [DMSB:0]chk_ptn = 0; -reg [DMSB:0]chk_ptn_next; -reg [DMSB:0]chk_dat = 0; -reg [DMSB:0]chk_dat_next; -reg chk = 0; -reg chk_next; - -reg error_next; - -reg [20:0]colormap = 21'b111110101100011010001; -reg [20:0]colormap_next; - -always_comb begin - state_next = state; - error_next = error; - count_next = count; - rd_addr_next = rd_addr; - rd_req_next = rd_req; - rd_len_next = rd_len; - wr_addr_next = wr_addr; - wr_data_next = wr_data; - wr_req_next = wr_req; - wr_len_next = wr_len; - pattern0_reset_next = 0; - pattern1_reset_next = 0; - pattern0_step_next = 0; - pattern1_step_next = 0; - colormap_next = colormap; - info_next = info; - info_e_next = 0; - - chk_ptn_next = chk_ptn; - chk_dat_next = chk_dat; - chk_next = 0; - - // verify pipeline 1: capture read data and pattern - if (rd_rdy) begin - chk_ptn_next = pattern1[DMSB:0]; - chk_dat_next = rd_data; - chk_next = 1; - pattern1_step_next = 1; - end - - // verify pipeline 2: compare and flag errors - if (chk) begin - error_next = (chk_ptn != chk_dat); - end - - case (state) - START: if (count_done) begin - state_next = START2; - info_e_next = 1; - info_next = { 1'b0, colormap[2:0], 4'h0, 6'h0, rd_addr[19:18] }; - end else begin - count_next = count_minus_one; - end - START2: begin - info_e_next = 1; - info_next = { 1'b0, colormap[2:0], 4'h0, rd_addr[17:10] }; - state_next = WRITE; - count_next = BLOCK; - colormap_next = { colormap[2:0], colormap[20:3] }; - end - WRITE: if (count_done) begin - state_next = READ; -`ifdef READX16 - count_next = 63; -`else - count_next = BLOCK; -`endif - end else begin - if (wr_req) begin - if (wr_ack) begin - wr_req_next = 0; - wr_addr_next = wr_addr + 1; - pattern0_step_next = 1; - count_next = count_minus_one; - end - end else begin - wr_req_next = 1; - wr_data_next = pattern0[DMSB:0]; - end - end - READ: if (count_done) begin - //info_e_next = 1; - //info_next = 16'h72CC; - state_next = START; - count_next = BLOCK; - end else begin - if (rd_req) begin - if (rd_ack) begin - rd_req_next = 0; -`ifdef READX16 - rd_addr_next = rd_addr + 16; -`else - rd_addr_next = rd_addr + 1; -`endif - count_next = count_minus_one; - end - end else begin - rd_req_next = 1; -`ifdef READX16 - rd_len_next = 15; -`endif - end - end - HALT: state_next = HALT; - default: state_next = HALT; - endcase - - if (error) begin - state_next = HALT; - info_next = { 16'h40EE }; - info_e_next = 1; - error_next = 0; - rd_req_next = 0; - wr_req_next = 0; - end -end - -reg reset = 1; - -always_ff @(posedge clk) begin - reset <= 0; - state <= state_next; - count <= count_next; - rd_addr <= rd_addr_next; - rd_req <= rd_req_next; - rd_len <= rd_len_next; - wr_addr <= wr_addr_next; - wr_data <= wr_data_next; - wr_req <= wr_req_next; - wr_len <= wr_len_next; - pattern0_reset <= pattern0_reset_next; - pattern1_reset <= pattern1_reset_next; - pattern0_step <= pattern0_step_next; - pattern1_step <= pattern1_step_next; - info <= info_next; - info_e <= info_e_next; - chk <= chk_next; - chk_dat <= chk_dat_next; - chk_ptn <= chk_ptn_next; - error <= error_next; - colormap <= colormap_next; -end - -xorshift32 xs0( - .clk(clk), - .next(pattern0_step_next), - .reset(pattern0_reset), - .data(pattern0) -); -xorshift32 xs1( - .clk(clk), - .next(pattern1_step_next), - .reset(pattern1_reset), - .data(pattern1) -); - -sdram #( - .T_PWR_UP(T_PWR_UP), - .T_RI(T_RI) - ) sdram0 ( - .clk(clk), - .reset(reset), - - .pin_clk(sdram_clk), - .pin_ras_n(sdram_ras_n), - .pin_cas_n(sdram_cas_n), - .pin_we_n(sdram_we_n), - .pin_addr(sdram_addr), -`ifdef verilator - .pin_data_i(sdram_data_i), - .pin_data_o(sdram_data_o), -`else - .pin_data(sdram_data), -`endif - -`ifdef SWIZZLE - .rd_addr({rd_addr[7:4],rd_addr[19:8],rd_addr[3:0]}), - .wr_addr({wr_addr[7:4],wr_addr[19:8],wr_addr[3:0]}), -`else - .rd_addr(rd_addr), - .wr_addr(wr_addr), -`endif - //.wr_addr({wr_addr[19:13], 1'b0, wr_addr[11:0]}), // force error - - .rd_len(rd_len), - .rd_req(rd_req), - .rd_ack(rd_ack), - .rd_data(rd_data), - .rd_rdy(rd_rdy), - - .wr_data(wr_data), - .wr_len(wr_len), - .wr_req(wr_req), - .wr_ack(wr_ack) -); - -endmodule diff --git a/hdl/ulx3s-sdram.sv b/hdl/ulx3s-sdram.sv @@ -0,0 +1,120 @@ +// Copyright 2020, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. + +`default_nettype none + +module top( + input wire clk_25mhz, + + output wire [7:0]led, + + output sdram_clk, + output sdram_ras_n, + output sdram_cas_n, + output sdram_we_n, + output [14:0]sdram_addr, + inout [15:0]sdram_data, + + output sdram_cke, + output sdram_cs_n, + output [1:0]sdram_dqm +); + +assign sdram_cke = 1; +assign sdram_cs_n = 0; +assign sdram_dqm = 2'b00; + +wire clk25m = clk_25mhz; +wire clk100m; + +pll_25_100 pll( + .clk25m_in(clk25m), + .clk100m_out(clk100m), + .locked() +); + +wire testclk = clk100m; + +wire [24:0]rd_addr; +wire [15:0]rd_data; +wire [3:0]rd_len; +wire rd_req; +wire rd_ack; +wire rd_rdy; + +wire [24:0]wr_addr; +wire [15:0]wr_data; +wire wr_req; +wire wr_ack; +wire [3:0]wr_len; + +assign led = wr_addr[24:17]; + +testbench #( + .BANKBITS(2), + .ROWBITS(13), + .COLBITS(10) + ) test0 ( + .clk(testclk), + .error(), + .done(), + + .rd_addr(rd_addr), + .rd_data(rd_data), + .rd_len(rd_len), + .rd_req(rd_req), + .rd_ack(rd_ack), + .rd_rdy(rd_rdy), + + .wr_addr(wr_addr), + .wr_data(wr_data), + .wr_len(wr_len), + .wr_req(wr_req), + .wr_ack(wr_ack), + + .info(), + .info_e() +); + +sdram #( + .BANKBITS(2), + .ROWBITS(13), + .COLBITS(10), + .T_PWR_UP(25000), + .T_RI(750), + .T_RCD(3), + .CLK_SHIFT(0), + .CLK_DELAY(127) + ) sdram0 ( + .clk(testclk), + .reset(0), + + .pin_clk(sdram_clk), + .pin_ras_n(sdram_ras_n), + .pin_cas_n(sdram_cas_n), + .pin_we_n(sdram_we_n), + .pin_addr(sdram_addr), + .pin_data(sdram_data), + +`ifdef SWIZZLE + .rd_addr({rd_addr[7:4],rd_addr[19:8],rd_addr[3:0]}), + .wr_addr({wr_addr[7:4],wr_addr[19:8],wr_addr[3:0]}), +`else + .rd_addr(rd_addr), + .wr_addr(wr_addr), +`endif + + .rd_data(rd_data), + .rd_len(rd_len), + .rd_req(rd_req), + .rd_ack(rd_ack), + .rd_rdy(rd_rdy), + + .wr_data(wr_data), + .wr_len(wr_len), + .wr_req(wr_req), + .wr_ack(wr_ack) +); + +endmodule + diff --git a/hdl/ulx3s.lpf b/hdl/ulx3s.lpf @@ -0,0 +1,462 @@ +BLOCK RESETPATHS; +BLOCK ASYNCPATHS; +## ULX3S v2.x.x and v3.0.x + +# The clock "usb" and "gpdi" sheet +LOCATE COMP "clk_25mhz" SITE "G2"; +IOBUF PORT "clk_25mhz" PULLMODE=NONE IO_TYPE=LVCMOS33; +FREQUENCY PORT "clk_25mhz" 25 MHZ; + +# JTAG and SPI FLASH voltage 3.3V and options to boot from SPI flash +# write to FLASH possible any time from JTAG: +#SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 MASTER_SPI_PORT=ENABLE SLAVE_SPI_PORT=DISABLE SLAVE_PARALLEL_PORT=DISABLE; +# write to FLASH possible from user bitstream: +SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 MASTER_SPI_PORT=DISABLE SLAVE_SPI_PORT=DISABLE SLAVE_PARALLEL_PORT=DISABLE; + +## USBSERIAL FTDI-FPGA serial port "usb" sheet +LOCATE COMP "ftdi_rxd" SITE "L4"; # FPGA transmits to ftdi +LOCATE COMP "ftdi_txd" SITE "M1"; # FPGA receives from ftdi +LOCATE COMP "ftdi_nrts" SITE "M3"; # FPGA receives +LOCATE COMP "ftdi_ndtr" SITE "N1"; # FPGA receives +LOCATE COMP "ftdi_txden" SITE "L3"; # FPGA receives +IOBUF PORT "ftdi_rxd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "ftdi_txd" PULLMODE=UP IO_TYPE=LVCMOS33; +IOBUF PORT "ftdi_nrts" PULLMODE=UP IO_TYPE=LVCMOS33; +IOBUF PORT "ftdi_ndtr" PULLMODE=UP IO_TYPE=LVCMOS33; +IOBUF PORT "ftdi_txden" PULLMODE=UP IO_TYPE=LVCMOS33; + +## LED indicators "blinkey" and "gpio" sheet +LOCATE COMP "led[7]" SITE "H3"; +LOCATE COMP "led[6]" SITE "E1"; +LOCATE COMP "led[5]" SITE "E2"; +LOCATE COMP "led[4]" SITE "D1"; +LOCATE COMP "led[3]" SITE "D2"; +LOCATE COMP "led[2]" SITE "C1"; +LOCATE COMP "led[1]" SITE "C2"; +LOCATE COMP "led[0]" SITE "B2"; +IOBUF PORT "led[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "led[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; + +## Pushbuttons "blinkey", "flash", "power", "gpdi" sheet +LOCATE COMP "btn[0]" SITE "D6"; # BTN_PWRn (inverted logic) +LOCATE COMP "btn[1]" SITE "R1"; # FIRE1 +LOCATE COMP "btn[2]" SITE "T1"; # FIRE2 +LOCATE COMP "btn[3]" SITE "R18"; # UP +LOCATE COMP "btn[4]" SITE "V1"; # DOWN +LOCATE COMP "btn[5]" SITE "U1"; # LEFT +LOCATE COMP "btn[6]" SITE "H16"; # RIGHT +IOBUF PORT "btn[0]" PULLMODE=UP IO_TYPE=LVCMOS33; +IOBUF PORT "btn[1]" PULLMODE=DOWN IO_TYPE=LVCMOS33; +IOBUF PORT "btn[2]" PULLMODE=DOWN IO_TYPE=LVCMOS33; +IOBUF PORT "btn[3]" PULLMODE=DOWN IO_TYPE=LVCMOS33; +IOBUF PORT "btn[4]" PULLMODE=DOWN IO_TYPE=LVCMOS33; +IOBUF PORT "btn[5]" PULLMODE=DOWN IO_TYPE=LVCMOS33; +IOBUF PORT "btn[6]" PULLMODE=DOWN IO_TYPE=LVCMOS33; + +## DIP switch "blinkey", "gpio" sheet +LOCATE COMP "sw[0]" SITE "E8"; # SW1 +LOCATE COMP "sw[1]" SITE "D8"; # SW2 +LOCATE COMP "sw[2]" SITE "D7"; # SW3 +LOCATE COMP "sw[3]" SITE "E7"; # SW4 +IOBUF PORT "sw[0]" PULLMODE=DOWN IO_TYPE=LVCMOS33; +IOBUF PORT "sw[1]" PULLMODE=DOWN IO_TYPE=LVCMOS33; +IOBUF PORT "sw[2]" PULLMODE=DOWN IO_TYPE=LVCMOS33; +IOBUF PORT "sw[3]" PULLMODE=DOWN IO_TYPE=LVCMOS33; + +## SPI OLED DISPLAY SSD1331 (Color) or SSD1306 (B/W) "blinkey", "usb" sheet +LOCATE COMP "oled_clk" SITE "P4"; +LOCATE COMP "oled_mosi" SITE "P3"; +LOCATE COMP "oled_dc" SITE "P1"; +LOCATE COMP "oled_resn" SITE "P2"; +LOCATE COMP "oled_csn" SITE "N2"; +IOBUF PORT "oled_clk" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "oled_mosi" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "oled_dc" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "oled_resn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "oled_csn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## SPI Flash chip "flash" sheet +LOCATE COMP "flash_csn" SITE "R2"; +#LOCATE COMP "flash_clk" SITE "U3"; +LOCATE COMP "flash_mosi" SITE "W2"; +LOCATE COMP "flash_miso" SITE "V2"; +LOCATE COMP "flash_holdn" SITE "W1"; +LOCATE COMP "flash_wpn" SITE "Y2"; +#LOCATE COMP "flash_csspin" SITE "AJ3"; +#LOCATE COMP "flash_initn" SITE "AG4"; +#LOCATE COMP "flash_done" SITE "AJ4"; +#LOCATE COMP "flash_programn" SITE "AH4"; +#LOCATE COMP "flash_cfg_select[0]" SITE "AM4"; +#LOCATE COMP "flash_cfg_select[1]" SITE "AL4"; +#LOCATE COMP "flash_cfg_select[2]" SITE "AK4"; +IOBUF PORT "flash_csn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_clk" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "flash_mosi" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "flash_miso" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "flash_holdn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "flash_wpn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_csspin" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_initn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_done" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_programn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_cfg_select[0]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_cfg_select[1]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "flash_cfg_select[2]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; + +## SD card "sdcard", "usb" sheet +LOCATE COMP "sd_clk" SITE "H2"; # sd_clk WiFi_GPIO14 +LOCATE COMP "sd_cmd" SITE "J1"; # sd_cmd_di (MOSI) WiFi GPIO15 +LOCATE COMP "sd_d[0]" SITE "J3"; # sd_dat0_do (MISO) WiFi GPIO2 +LOCATE COMP "sd_d[1]" SITE "H1"; # sd_dat1_irq WiFi GPIO4 +LOCATE COMP "sd_d[2]" SITE "K1"; # sd_dat2 WiFi_GPIO12 +LOCATE COMP "sd_d[3]" SITE "K2"; # sd_dat3_csn WiFi_GPIO13 +LOCATE COMP "sd_wp" SITE "P5"; # not connected +LOCATE COMP "sd_cdn" SITE "N5"; # not connected +IOBUF PORT "sd_clk" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_cmd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_d[0]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_d[1]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_d[2]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; # WiFi GPIO12 pulldown bootstrapping requirement +IOBUF PORT "sd_d[3]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_wp" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sd_cdn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## ADC SPI (MAX11123) "analog", "ram" sheet +LOCATE COMP "adc_csn" SITE "R17"; +LOCATE COMP "adc_mosi" SITE "R16"; +LOCATE COMP "adc_miso" SITE "U16"; +LOCATE COMP "adc_sclk" SITE "P17"; +IOBUF PORT "adc_csn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "adc_mosi" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "adc_miso" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "adc_sclk" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## Audio 4-bit DAC "analog", "gpio" sheet +# Output impedance 75 ohm. +# Strong enough to drive 16 ohm earphones. +LOCATE COMP "audio_l[3]" SITE "B3"; # JACK TIP (left audio) +LOCATE COMP "audio_l[2]" SITE "C3"; +LOCATE COMP "audio_l[1]" SITE "D3"; +LOCATE COMP "audio_l[0]" SITE "E4"; +LOCATE COMP "audio_r[3]" SITE "C5"; # JACK RING1 (right audio) +LOCATE COMP "audio_r[2]" SITE "D5"; +LOCATE COMP "audio_r[1]" SITE "B5"; +LOCATE COMP "audio_r[0]" SITE "A3"; +LOCATE COMP "audio_v[3]" SITE "E5"; # JACK RING2 (video or digital audio) +LOCATE COMP "audio_v[2]" SITE "F5"; +LOCATE COMP "audio_v[1]" SITE "F2"; +LOCATE COMP "audio_v[0]" SITE "H5"; +IOBUF PORT "audio_l[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_l[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_l[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_l[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_r[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_r[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_r[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_r[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_v[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_v[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_v[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "audio_v[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; + +## WiFi ESP-32 "wifi", "usb", "flash" sheet +# other pins are shared with GP/GN, SD card and JTAG +LOCATE COMP "wifi_en" SITE "F1"; # enable/reset WiFi +LOCATE COMP "wifi_rxd" SITE "K3"; # FPGA transmits to WiFi +LOCATE COMP "wifi_txd" SITE "K4"; # FPGA receives from WiFi +LOCATE COMP "wifi_gpio0" SITE "L2"; +LOCATE COMP "wifi_gpio5" SITE "N4"; # WIFI LED +LOCATE COMP "wifi_gpio16" SITE "L1"; # Serial1 RX +LOCATE COMP "wifi_gpio17" SITE "N3"; # Serial1 TX +# LOCATE COMP "prog_done" SITE "Y3"; # not GPIO, always active +IOBUF PORT "wifi_en" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_rxd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_txd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_gpio0" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_gpio5" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_gpio16" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "wifi_gpio17" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +# IOBUF PORT "prog_done" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## PCB antenna 433 MHz (may be also used for FM) "usb" sheet +LOCATE COMP "ant_433mhz" SITE "G1"; +IOBUF PORT "ant_433mhz" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; + +## Second USB port "US2" going directly into FPGA "usb", "ram" sheet +LOCATE COMP "usb_fpga_dp" SITE "E16"; # single ended or differential input only +LOCATE COMP "usb_fpga_dn" SITE "F16"; +IOBUF PORT "usb_fpga_dp" PULLMODE=NONE IO_TYPE=LVCMOS33D DRIVE=16; +IOBUF PORT "usb_fpga_dn" PULLMODE=NONE IO_TYPE=LVCMOS33D DRIVE=16; +LOCATE COMP "usb_fpga_bd_dp" SITE "D15"; # single-ended bidirectional +LOCATE COMP "usb_fpga_bd_dn" SITE "E15"; +IOBUF PORT "usb_fpga_bd_dp" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "usb_fpga_bd_dn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +LOCATE COMP "usb_fpga_pu_dp" SITE "B12"; # pull up/down control +LOCATE COMP "usb_fpga_pu_dn" SITE "C12"; +IOBUF PORT "usb_fpga_pu_dp" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; +IOBUF PORT "usb_fpga_pu_dn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16; + +## JTAG ESP-32 "usb" sheet +# connected to FT231X and ESP-32 +# commented out because those are dedicated pins, not directly useable as GPIO +# but could be used by some vendor-specific JTAG bridging (boundary scan) module +#LOCATE COMP "jtag_tdi" SITE "R5"; # FTDI_nRI FPGA receives +#LOCATE COMP "jtag_tdo" SITE "V4"; # FTDI_nCTS FPGA transmits +#LOCATE COMP "jtag_tck" SITE "T5"; # FTDI_nDSR FPGA receives +#LOCATE COMP "jtag_tms" SITE "U5"; # FTDI_nDCD FPGA receives +#IOBUF PORT "jtag_tdi" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "jtag_tdo" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "jtag_tck" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +#IOBUF PORT "jtag_tms" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## SDRAM "ram" sheet +LOCATE COMP "sdram_clk" SITE "F19"; +LOCATE COMP "sdram_cke" SITE "F20"; +LOCATE COMP "sdram_cs_n" SITE "P20"; +LOCATE COMP "sdram_we_n" SITE "T20"; +LOCATE COMP "sdram_ras_n" SITE "R20"; +LOCATE COMP "sdram_cas_n" SITE "T19"; +LOCATE COMP "sdram_addr[0]" SITE "M20"; +LOCATE COMP "sdram_addr[1]" SITE "M19"; +LOCATE COMP "sdram_addr[2]" SITE "L20"; +LOCATE COMP "sdram_addr[3]" SITE "L19"; +LOCATE COMP "sdram_addr[4]" SITE "K20"; +LOCATE COMP "sdram_addr[5]" SITE "K19"; +LOCATE COMP "sdram_addr[6]" SITE "K18"; +LOCATE COMP "sdram_addr[7]" SITE "J20"; +LOCATE COMP "sdram_addr[8]" SITE "J19"; +LOCATE COMP "sdram_addr[9]" SITE "H20"; +LOCATE COMP "sdram_addr[10]" SITE "N19"; +LOCATE COMP "sdram_addr[11]" SITE "G20"; +LOCATE COMP "sdram_addr[12]" SITE "G19"; +LOCATE COMP "sdram_addr[13]" SITE "P19"; +LOCATE COMP "sdram_addr[14]" SITE "N20"; +LOCATE COMP "sdram_dqm[0]" SITE "U19"; +LOCATE COMP "sdram_dqm[1]" SITE "E20"; +LOCATE COMP "sdram_data[0]" SITE "J16"; +LOCATE COMP "sdram_data[1]" SITE "L18"; +LOCATE COMP "sdram_data[2]" SITE "M18"; +LOCATE COMP "sdram_data[3]" SITE "N18"; +LOCATE COMP "sdram_data[4]" SITE "P18"; +LOCATE COMP "sdram_data[5]" SITE "T18"; +LOCATE COMP "sdram_data[6]" SITE "T17"; +LOCATE COMP "sdram_data[7]" SITE "U20"; +LOCATE COMP "sdram_data[8]" SITE "E19"; +LOCATE COMP "sdram_data[9]" SITE "D20"; +LOCATE COMP "sdram_data[10]" SITE "D19"; +LOCATE COMP "sdram_data[11]" SITE "C20"; +LOCATE COMP "sdram_data[12]" SITE "E18"; +LOCATE COMP "sdram_data[13]" SITE "F18"; +LOCATE COMP "sdram_data[14]" SITE "J18"; +LOCATE COMP "sdram_data[15]" SITE "J17"; +IOBUF PORT "sdram_clk" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_cke" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_cs_n" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_we_n" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_ras_n" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_cas_n" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[8]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[9]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[10]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[11]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[12]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[13]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_addr[14]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_dqm[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_dqm[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[8]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[9]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[10]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[11]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[12]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[13]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[14]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "sdram_data[15]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; + +# GPDI differential interface (Video) "gpdi" sheet +LOCATE COMP "gpdi_dp[0]" SITE "A16"; # Blue + +LOCATE COMP "gpdi_dn[0]" SITE "B16"; # Blue - +LOCATE COMP "gpdi_dp[1]" SITE "A14"; # Green + +LOCATE COMP "gpdi_dn[1]" SITE "C14"; # Green - +LOCATE COMP "gpdi_dp[2]" SITE "A12"; # Red + +LOCATE COMP "gpdi_dn[2]" SITE "A13"; # Red - +LOCATE COMP "gpdi_dp[3]" SITE "A17"; # Clock + +LOCATE COMP "gpdi_dn[3]" SITE "B18"; # Clock - +LOCATE COMP "gpdi_ethp" SITE "A19"; # Ethernet + +LOCATE COMP "gpdi_ethn" SITE "B20"; # Ethernet - +LOCATE COMP "gpdi_cec" SITE "A18"; +LOCATE COMP "gpdi_sda" SITE "B19"; # I2C shared with RTC +LOCATE COMP "gpdi_scl" SITE "E12"; # I2C shared with RTC C12->E12 +IOBUF PORT "gpdi_dp[0]" IO_TYPE=LVCMOS33D DRIVE=4; +IOBUF PORT "gpdi_dn[0]" IO_TYPE=LVCMOS33D DRIVE=4; +IOBUF PORT "gpdi_dp[1]" IO_TYPE=LVCMOS33D DRIVE=4; +IOBUF PORT "gpdi_dn[1]" IO_TYPE=LVCMOS33D DRIVE=4; +IOBUF PORT "gpdi_dp[2]" IO_TYPE=LVCMOS33D DRIVE=4; +IOBUF PORT "gpdi_dn[2]" IO_TYPE=LVCMOS33D DRIVE=4; +IOBUF PORT "gpdi_dp[3]" IO_TYPE=LVCMOS33D DRIVE=4; +IOBUF PORT "gpdi_dn[3]" IO_TYPE=LVCMOS33D DRIVE=4; +IOBUF PORT "gpdi_ethp" IO_TYPE=LVCMOS33D DRIVE=4; +IOBUF PORT "gpdi_ethn" IO_TYPE=LVCMOS33D DRIVE=4; +IOBUF PORT "gpdi_cec" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_sda" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gpdi_scl" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +# GPIO (default single-ended) "gpio", "ram", "gpdi" sheet +# Physical connector pins: +# *** when FEMALE ANGLED (90 deg PMOD) soldered *** +# Jm_n- = Jm_n, Jm_n+ = Jm_n+1 +# example: J1_5- is J1_5 phsyical, J1_5+ is J1_6 physical +# *** when MALE VERTICAL soldered *** +# Jm_n+ = Jm_n, Jm_n- = Jm_n+1 +# example: J1_5+ is J1_5 physical, J1_5- is J1_6 physical +# Pins enumerated gp[0-27], gn[0-27]. +# With differential mode enabled on Lattice, +# gp[] (+) are used, gn[] (-) are ignored from design +# as they handle inverted signal by default. +# To enable differential, rename LVCMOS33->LVCMOS33D +# To enable clock i/o, add this (example): +#FREQUENCY PORT "gp[12]" 25.00 MHZ; +LOCATE COMP "gp[0]" SITE "B11"; # J1_5+ GP0 PCLK +LOCATE COMP "gn[0]" SITE "C11"; # J1_5- GN0 PCLK +LOCATE COMP "gp[1]" SITE "A10"; # J1_7+ GP1 PCLK +LOCATE COMP "gn[1]" SITE "A11"; # J1_7- GN1 PCLK +LOCATE COMP "gp[2]" SITE "A9"; # J1_9+ GP2 GR_PCLK +LOCATE COMP "gn[2]" SITE "B10"; # J1_9- GN2 GR_PCLK +LOCATE COMP "gp[3]" SITE "B9"; # J1_11+ GP3 +LOCATE COMP "gn[3]" SITE "C10"; # J1_11- GN3 +LOCATE COMP "gp[4]" SITE "A7"; # J1_13+ GP4 +LOCATE COMP "gn[4]" SITE "A8"; # J1_13- GN4 +LOCATE COMP "gp[5]" SITE "C8"; # J1_15+ GP5 +LOCATE COMP "gn[5]" SITE "B8"; # J1_15- GN5 +LOCATE COMP "gp[6]" SITE "C6"; # J1_17+ GP6 +LOCATE COMP "gn[6]" SITE "C7"; # J1_17- GN6 +IOBUF PORT "gp[0]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[0]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[1]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[1]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[2]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[2]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[3]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[3]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[4]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[4]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[5]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[5]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[6]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[6]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +LOCATE COMP "gp[7]" SITE "A6"; # J1_23+ GP7 +LOCATE COMP "gn[7]" SITE "B6"; # J1_23- GN7 +LOCATE COMP "gp[8]" SITE "A4"; # J1_25+ GP8 +LOCATE COMP "gn[8]" SITE "A5"; # J1_25- GN8 DIFF +LOCATE COMP "gp[9]" SITE "A2"; # J1_27+ GP9 DIFF +LOCATE COMP "gn[9]" SITE "B1"; # J1_27- GN9 DIFF +LOCATE COMP "gp[10]" SITE "C4"; # J1_29+ GP10 DIFF +LOCATE COMP "gn[10]" SITE "B4"; # J1_29- GN10 DIFF +LOCATE COMP "gp[11]" SITE "F4"; # J1_31+ GP11 DIFF WIFI_GPIO26 +LOCATE COMP "gn[11]" SITE "E3"; # J1_31- GN11 DIFF WIFI_GPIO25 +LOCATE COMP "gp[12]" SITE "G3"; # J1_33+ GP12 DIFF WIFI_GPIO33 PCLK +LOCATE COMP "gn[12]" SITE "F3"; # J1_33- GN12 DIFF WIFI_GPIO32 PCLK +LOCATE COMP "gp[13]" SITE "H4"; # J1_35+ GP13 DIFF WIFI_GPIO35 +LOCATE COMP "gn[13]" SITE "G5"; # J1_35- GN13 DIFF WIFI_GPIO34 +IOBUF PORT "gp[7]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[7]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[8]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[8]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[9]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[9]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[10]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[10]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[11]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[11]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[12]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[12]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[13]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[13]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +LOCATE COMP "gp[14]" SITE "U18"; # J2_5+ GP14 DIFF ADC1 +LOCATE COMP "gn[14]" SITE "U17"; # J2_5- GN14 DIFF ADC0 +LOCATE COMP "gp[15]" SITE "N17"; # J2_7+ GP15 DIFF ADC3 +LOCATE COMP "gn[15]" SITE "P16"; # J2_7- GN15 DIFF ADC2 +LOCATE COMP "gp[16]" SITE "N16"; # J2_9+ GP16 DIFF ADC5 +LOCATE COMP "gn[16]" SITE "M17"; # J2_9- GN16 DIFF ADC4 +LOCATE COMP "gp[17]" SITE "L16"; # J2_11+ GP17 DIFF ADC7 GR_PCLK +LOCATE COMP "gn[17]" SITE "L17"; # J2_11- GN17 DIFF ADC6 +LOCATE COMP "gp[18]" SITE "H18"; # J2_13+ GP18 DIFF +LOCATE COMP "gn[18]" SITE "H17"; # J2_13- GN18 DIFF +LOCATE COMP "gp[19]" SITE "F17"; # J2_15+ GP19 DIFF +LOCATE COMP "gn[19]" SITE "G18"; # J2_15- GN19 DIFF +LOCATE COMP "gp[20]" SITE "D18"; # J2_17+ GP20 DIFF +LOCATE COMP "gn[20]" SITE "E17"; # J2_17- GN20 DIFF +IOBUF PORT "gp[14]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[14]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[15]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[15]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[16]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[16]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[17]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[17]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[18]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[18]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[19]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[19]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[20]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[20]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +LOCATE COMP "gp[21]" SITE "C18"; # J2_23+ GP21 DIFF +LOCATE COMP "gn[21]" SITE "D17"; # J2_23- GN21 DIFF +LOCATE COMP "gp[22]" SITE "B15"; # J2_25+ GP22 +LOCATE COMP "gn[22]" SITE "C15"; # J2_25- GN22 +LOCATE COMP "gp[23]" SITE "B17"; # J2_27+ GP23 +LOCATE COMP "gn[23]" SITE "C17"; # J2_27- GN23 +LOCATE COMP "gp[24]" SITE "C16"; # J2_29+ GP24 +LOCATE COMP "gn[24]" SITE "D16"; # J2_29- GN24 +LOCATE COMP "gp[25]" SITE "D14"; # J2_31+ GP25 +LOCATE COMP "gn[25]" SITE "E14"; # J2_31- GN25 +LOCATE COMP "gp[26]" SITE "B13"; # J2_33+ GP26 +LOCATE COMP "gn[26]" SITE "C13"; # J2_33- GN26 +LOCATE COMP "gp[27]" SITE "D13"; # J2_35+ GP27 +LOCATE COMP "gn[27]" SITE "E13"; # J2_35- GN27 +IOBUF PORT "gp[21]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[21]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[22]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[22]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[23]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[23]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[24]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[24]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[25]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[25]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[26]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[26]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gp[27]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; +IOBUF PORT "gn[27]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## PROGRAMN (reload bitstream from FLASH, exit from bootloader) +# PCB v2.0.5 and higher +LOCATE COMP "user_programn" SITE "M4"; +IOBUF PORT "user_programn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; + +## SHUTDOWN "power", "ram" sheet (connected from PCB v1.7.5) +# on PCB v1.7 shutdown is not connected to FPGA +LOCATE COMP "shutdown" SITE "G16"; # FPGA receives +IOBUF PORT "shutdown" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4; diff --git a/project/colorlight-sdram.def b/project/colorlight-sdram.def @@ -4,7 +4,7 @@ PROJECT_SRCS := hdl/colorlight-sdram.sv hdl/colorlight.lpf PROJECT_SRCS += hdl/lattice/ecp5_pll_25_125_250.v PROJECT_SRCS += hdl/lattice/ecp5_pll_25_100.v PROJECT_SRCS += hdl/display/display.sv hdl/display/display_timing.sv -PROJECT_SRCS += hdl/sdram/testbench.sv hdl/sdram/test.hex +PROJECT_SRCS += hdl/sdram/memtest1.sv PROJECT_SRCS += hdl/sdram/sdram.sv hdl/sdram/sdram_glue_ecp5.sv PROJECT_SRCS += hdl/xorshift.sv diff --git a/project/ulx3s-sdram.def b/project/ulx3s-sdram.def @@ -0,0 +1,9 @@ +PROJECT_TYPE := nextpnr-ecp5 + +PROJECT_SRCS := hdl/ulx3s-sdram.sv hdl/ulx3s.lpf +PROJECT_SRCS += hdl/lattice/ecp5_pll_25_100.v +PROJECT_SRCS += hdl/sdram/memtest1.sv +PROJECT_SRCS += hdl/sdram/sdram.sv hdl/sdram/sdram_glue_ecp5.sv +PROJECT_SRCS += hdl/xorshift.sv + +PROJECT_NEXTPNR_OPTS := --85k --package CABGA381 --speed 6 diff --git a/src/astl.c b/src/astl.c @@ -1,112 +0,0 @@ -// Copyright 2015, Brian Swetland <swetland@frotz.net> -// Licensed under the Apache License, Version 2.0. - -#include <stdio.h> -#include <stdint.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> - -struct { - uint64_t enc; - const char* name; - const char* args; - const char* desc; -} ops[] = { - { 0x100000000, "wri", "w", "wri # write immediate" }, - { 0x200000000, "wrp", "w", "wrp # write pattern0 #+1 times" }, - { 0x300000000, "rdc", "w", "rdi # read + check vs immediate" }, - { 0x400000000, "rdp", "w", "rdp # read + check vs pattern1 #+1 times" }, - { 0x500000000, "verify","w", "rdp check count readbuffer vs pattern1" }, - { 0x600000000, "rdf", "w", "rdp read count into readbuffer" }, - { 0x700000000, "rdb", "w", "rdp read burst count into readbuffer" }, - { 0xA00000000, "addr", "w", "addr # set address" }, - { 0xF00000000, "wait", "w", "wait # wait # cycles" }, - { 0x080000000, "halt", "", "halt stop processing" }, - { 0x040000000, "dump", "w", "dump display # scope traces" }, - { 0x020000000, "trigger","", "trigger trigger scope capture" }, - { 0x000000001, "p0rst", "", "p0rst reset pattern0" }, - { 0x000000002, "p1rst", "", "p1rst reset pattern1" }, - { 0x000000004, "auto+", "", "auto+ enable addr auto inc" }, - { 0x000000008, "auto-", "", "auto- disble addr auto inc" }, - { 0xD00007100, "show", "b", "show # show status byte" }, - { 0x000000000, "", "", "" }, -}; - -unsigned lineno = 1; - -const char* token(void) { - static char buf[64]; - int n = 0; - for (;;) { - int c = getchar(); - if (c == '#') { // comment to EOL - for (;;) { - c = getchar(); - if (c == EOF) break; - if (c == '\n') break; - } - } - if (c == '\n') lineno++; - if (c == EOF) break; - if (isspace(c)) { - if (n) break; - } else { - buf[n++] = c; - if (n == sizeof(buf)) { - fprintf(stderr, "error: %u: token too large\n", lineno); - exit(-1); - } - } - } - buf[n] = 0; - return buf; -} - -uint32_t arg_word(const char* tok) { - if (tok[0] == 0) { - fprintf(stderr, "error: %u: missing argument\n", lineno); - exit(-1); - } - if (tok[0] == '.') return strtoul(tok+1, 0, 10); - else return strtoul(tok, 0, 16); -} -uint32_t arg_byte(const char* tok) { - uint32_t n = arg_word(tok); - if (n > 255) { - fprintf(stderr, "error: %u: byte argument too large\n", lineno); - exit(-1); - } - return n; -} - -int main(int argc, char **argv) { - if (argc != 1) { - for (unsigned n = 0; ops[n].enc; n++) { - fprintf(stderr, "%s\n", ops[n].desc); - } - return 0; - } - for (;;) { - const char* tok = token(); - if (tok[0] == 0) break; - for (unsigned n = 0; ops[n].enc; n++) { - if (!strcasecmp(ops[n].name, tok)) { - uint64_t op = ops[n].enc; - const char* args = ops[n].args; - while (*args) { - if (*args == 'w') op |= arg_word(token()); - if (*args == 'b') op |= arg_byte(token()); - args++; - } - printf("%09lx\n", op); - goto next; - } - } - fprintf(stderr, "error: %u: unknown opcode '%s'\n", lineno, tok); - exit(-1); -next: ; - } - printf("080000000\n"); - return 0; -}