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:
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;
-}