initial
authorThomas Pietrzak <thomas.pietrzak@gmail.com>
Thu, 11 Oct 2018 07:22:26 +0000 (09:22 +0200)
committerThomas Pietrzak <thomas.pietrzak@gmail.com>
Thu, 11 Oct 2018 07:22:26 +0000 (09:22 +0200)
.gitignore [new file with mode: 0644]
clocks.v [new file with mode: 0644]
lcd.ucf [new file with mode: 0644]
lcd.v [new file with mode: 0644]
spi.v [new file with mode: 0644]
top.v [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..c89fea8
--- /dev/null
@@ -0,0 +1,42 @@
+*.ngd
+*.pad
+*.par
+*.pcf
+*.prj
+*.ptwx
+*.stx
+*.syr
+*.twr
+*.twx
+*.unroutes
+*.xpi
+*.xst
+*.ncd
+*.map
+*.mrp
+*.ncd
+*.ngm
+*.xrpt
+*.csv
+*.txt
+*.xml
+*.bgn
+*.bit
+*.bld
+*.cmd_log
+*.drc
+*.lso
+*.ngc
+*.ngr
+*.ut
+*.xwbt
+*.html
+*.gise
+*.log
+_ngo
+_xmsgs
+ipcore_dir
+iseconfig
+netgen
+xlnx_auto_0_xdb
+xst
diff --git a/clocks.v b/clocks.v
new file mode 100644 (file)
index 0000000..1db0971
--- /dev/null
+++ b/clocks.v
@@ -0,0 +1,124 @@
+module clocks(
+  clkpin, // 50MHz
+  rst,
+  locked,
+  clk,    // 300MHz
+  spiclk, // 20MHz
+  tftclk  // 6.667MHz
+);
+
+input clkpin;
+input rst;
+output locked;
+output clk;
+output spiclk;
+output tftclk;
+
+wire GROUND;
+wire U1_CLKDV_BUF;
+wire U1_CLKFX_BUF;
+wire U1_CLKIN_IBUFG;
+wire U1_CLK0_BUF;
+wire U1_LOCKED_INV_IN;
+wire U2_CLKFB_IN;
+wire U2_CLKFX_BUF;
+wire U2_CLKIN_IN;
+wire U2_CLK0_BUF;
+wire U2_FDS_Q_OUT;
+wire U2_FD1_Q_OUT;
+wire U2_FD2_Q_OUT;
+wire U2_FD3_Q_OUT;
+wire U2_LOCKED_INV_RST;
+wire U2_OR3_O_OUT;
+wire U2_RST_IN;
+
+assign GROUND = 0;
+DCM_SP #(
+  .CLK_FEEDBACK("1X"),
+  .CLKDV_DIVIDE(2.5),
+  .CLKFX_DIVIDE(1),
+  .CLKFX_MULTIPLY(6),
+  .CLKIN_DIVIDE_BY_2("FALSE"),
+  .CLKIN_PERIOD(20.000),
+  .CLKOUT_PHASE_SHIFT("NONE"),
+  .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
+  .DFS_FREQUENCY_MODE("LOW"),
+  .DLL_FREQUENCY_MODE("LOW"),
+  .DUTY_CYCLE_CORRECTION("TRUE"),
+  .FACTORY_JF(16'hC080),
+  .PHASE_SHIFT(0),
+  .STARTUP_WAIT("FALSE")
+)
+DCM_SP_INST1(
+  .CLKFB(U2_CLKIN_IN),
+  .CLKIN(U1_CLKIN_IBUFG),
+  .DSSEN(GROUND), 
+  .PSCLK(GROUND), 
+  .PSEN(GROUND), 
+  .PSINCDEC(GROUND), 
+  .RST(rst), 
+  .CLKDV(U1_CLKDV_BUF), 
+  .CLKFX(U1_CLKFX_BUF), 
+  .CLKFX180(), 
+  .CLK0(U1_CLK0_BUF), 
+  .CLK2X(), 
+  .CLK2X180(), 
+  .CLK90(), 
+  .CLK180(), 
+  .CLK270(), 
+  .LOCKED(U1_LOCKED_INV_IN), 
+  .PSDONE(), 
+  .STATUS()
+);
+DCM_SP #(
+  .CLK_FEEDBACK("1X"),
+  .CLKDV_DIVIDE(2.0),
+  .CLKFX_DIVIDE(15),
+  .CLKFX_MULTIPLY(2),
+  .CLKIN_DIVIDE_BY_2("FALSE"),
+  .CLKIN_PERIOD(20.000),
+  .CLKOUT_PHASE_SHIFT("NONE"),
+  .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
+  .DFS_FREQUENCY_MODE("LOW"),
+  .DLL_FREQUENCY_MODE("LOW"),
+  .DUTY_CYCLE_CORRECTION("TRUE"),
+  .FACTORY_JF(16'hC080),
+  .PHASE_SHIFT(0),
+  .STARTUP_WAIT("FALSE")
+)
+DCM_SP_INST2(
+  .CLKFB(U2_CLKFB_IN), 
+  .CLKIN(U2_CLKIN_IN), 
+  .DSSEN(GROUND), 
+  .PSCLK(GROUND), 
+  .PSEN(GROUND), 
+  .PSINCDEC(GROUND), 
+  .RST(U2_RST_IN), 
+  .CLKDV(), 
+  .CLKFX(U2_CLKFX_BUF), 
+  .CLKFX180(), 
+  .CLK0(U2_CLK0_BUF), 
+  .CLK2X(), 
+  .CLK2X180(), 
+  .CLK90(), 
+  .CLK180(), 
+  .CLK270(), 
+  .LOCKED(locked), 
+  .PSDONE(), 
+  .STATUS()
+);
+BUFG U1_CLKDV_BUFG_INST(.I(U1_CLKDV_BUF), .O(spiclk));
+BUFG U1_CLKFX_BUFG_INST(.I(U1_CLKFX_BUF), .O(clk));
+IBUFG U1_CLKIN_IBUFG_INST(.I(clkpin), .O(U1_CLKIN_IBUFG));
+BUFG U1_CLK0_BUFG_INST(.I(U1_CLK0_BUF), .O(U2_CLKIN_IN));
+INV U1_INV_INST(.I(U1_LOCKED_INV_IN), .O(U2_LOCKED_INV_RST));
+BUFG U2_CLKFX_BUFG_INST(.I(U2_CLKFX_BUF), .O(tftclk));
+BUFG U2_CLK0_BUFG_INST(.I(U2_CLK0_BUF), .O(U2_CLKFB_IN));
+FDS U2_FDS_INST(.C(U2_CLKIN_IN), .D(GROUND), .S(GROUND), .Q(U2_FDS_Q_OUT));
+FD U2_FD1_INST(.C(U2_CLKIN_IN), .D(U2_FDS_Q_OUT), .Q(U2_FD1_Q_OUT));
+FD U2_FD2_INST(.C(U2_CLKIN_IN), .D(U2_FD1_Q_OUT), .Q(U2_FD2_Q_OUT));
+FD U2_FD3_INST(.C(U2_CLKIN_IN), .D(U2_FD2_Q_OUT), .Q(U2_FD3_Q_OUT));
+OR2 U2_OR2_INST(.I0(U2_LOCKED_INV_RST), .I1(U2_OR3_O_OUT), .O(U2_RST_IN));
+OR3 U2_OR3_INST(.I0(U2_FD3_Q_OUT), .I1(U2_FD2_Q_OUT), .I2(U2_FD1_Q_OUT), .O(U2_OR3_O_OUT));
+
+endmodule
diff --git a/lcd.ucf b/lcd.ucf
new file mode 100644 (file)
index 0000000..f24b1fa
--- /dev/null
+++ b/lcd.ucf
@@ -0,0 +1,57 @@
+//50Mhz clock
+NET "clkpin" LOC = "E12"| IOSTANDARD = LVCMOS33 ;
+
+NET "LED<2>" LOC = "U20" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
+NET "LED<0>" LOC = "R20" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
+NET "LED<1>" LOC = "T19" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
+
+NET "BUTTON" LOC = "T14" | IOSTANDARD = LVTTL | PULLDOWN ;
+
+//NET "RL" LOC = "A13" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "TB" LOC = "B13" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+
+/* LCD Input control */
+//NET "dclk" LOC = "A14" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "vsync" LOC = "B15" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "hsync" LOC = "A15" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "de" LOC = "A16" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+
+/* Data red */
+//NET "tft_r_pins<7>" LOC = "A17" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_r_pins<6>" LOC = "B17" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_r_pins<5>" LOC = "A18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_r_pins<4>" LOC = "C18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_r_pins<3>" LOC = "A19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_r_pins<2>" LOC = "B19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_r_pins<1>" LOC = "A20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_r_pins<0>" LOC = "B20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+
+
+/* Data green */
+//NET "tft_g_pins<7>" LOC = "D19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_g_pins<6>" LOC = "D18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_g_pins<5>" LOC = "E17" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_g_pins<4>" LOC = "D20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_g_pins<3>" LOC = "D21" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_g_pins<2>" LOC = "D22" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_g_pins<1>" LOC = "E22" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_g_pins<0>" LOC = "F18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+
+
+/* Data blue */
+//NET "tft_b_pins<7>" LOC = "F20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_b_pins<6>" LOC = "E20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_b_pins<5>" LOC = "G20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_b_pins<4>" LOC = "G19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_b_pins<3>" LOC = "H19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_b_pins<2>" LOC = "J18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_b_pins<1>" LOC = "K18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "tft_b_pins<0>" LOC = "K17" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+
+/* serial port */
+//NET "SDI" LOC = "K19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "SDO" LOC = "M20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "SCL" LOC = "K20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+//NET "CS" LOC = "L19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
+
+//NET "RESET" LOC = "L18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
diff --git a/lcd.v b/lcd.v
new file mode 100644 (file)
index 0000000..4e3aa35
--- /dev/null
+++ b/lcd.v
@@ -0,0 +1,72 @@
+module lcd(
+       input clkpin,
+       output reg [1:0]led,
+       output rl,
+       output tb,
+       output dclk,
+       output vsync,
+       output hsync,
+       output de,
+       output reg [7:0]tft_r_pins,
+       output reg [7:0]tft_g_pins,
+       output reg [7:0]tft_b_pins,
+       output sdi,
+       input sdo,
+       output scl,
+       output cs,
+       output reset
+    );
+
+wire clk;    // 300 MHz
+wire spiclk; // 20 MHz
+reg tftclk; // 6.522 Mhz
+
+dcm dcm_instance(
+       .CLKIN_IN(clkpin),
+       .CLKFX_OUT(clk),
+       .CLKDV_OUT(spiclk));
+       
+reg [4:0] counter;
+always @(posedge clk) 
+       if (counter == 23) 
+               begin counter <= 0; tftclk <= ~tftclk; end 
+       else
+               counter <= counter + 1;
+               
+always @(posedge clk) led <= 2'b0;
+
+assign rl = 0;
+assign tb = 0;
+assign vsync = 0;
+assign hsync = 0;
+assign de = 0;
+always @(posedge clk) tft_r_pins <= 8'b0;
+always @(posedge clk) tft_g_pins <= 8'b0;
+always @(posedge clk) tft_b_pins <= 8'b0;
+assign sdi = sdo;
+assign cs = 0;
+assign reset = 0;
+
+ODDR2 #(.DDR_ALIGNMENT("NONE"), .INIT(1'b0), .SRTYPE("SYNC"))
+       oddr2_spi_clk(
+               .Q(scl),
+               .C0(spiclk),
+               .C1(~spiclk),
+               .CE(1'b1),
+               .D0(1'b1),
+               .D1(1'b0),
+               .R(1'b0),
+               .S(1'b0));
+
+ODDR2 #(.DDR_ALIGNMENT("NONE"), .INIT(1'b0), .SRTYPE("SYNC"))
+       oddr2_tft_clk(
+               .Q(dclk),
+               .C0(tftclk),
+               .C1(~tftclk),
+               .CE(1'b1),
+               .D0(1'b1),
+               .D1(1'b0),
+               .R(1'b0),
+               .S(1'b0));
+
+endmodule
diff --git a/spi.v b/spi.v
new file mode 100644 (file)
index 0000000..5c8111d
--- /dev/null
+++ b/spi.v
@@ -0,0 +1,70 @@
+module master_spi
+#(
+  parameter WIDTH = 8
+)
+
+(
+  clk,
+  mosi,
+  miso,
+  ssel,
+  din,
+  dout,
+  ready,
+  enable
+);
+
+function integer log2;
+  input integer value;
+  begin
+    value = value - 1;
+    for (log2 = 0; value > 0; log2 = log2 + 1) value = value >> 1;
+  end
+endfunction
+
+input clk;
+input miso;
+output reg mosi = 0;
+output reg ssel = 1;
+input [WIDTH-1:0] din;
+output [WIDTH-1:0] dout;
+output reg ready;
+input enable;
+
+initial ready = 1;
+
+reg started = 0;
+reg [log2(WIDTH)-1:0] counter;
+reg [WIDTH-1:0] sp_in = 0;
+reg [WIDTH-1:0] sp_out = 0;
+
+assign dout = sp_out;
+
+always @(posedge clk) if (enable) begin
+  if (!started) begin
+    sp_in <= din;
+    sp_out <= 0;
+    started <= 1;
+    ssel <= 1;
+    ready <= 0;
+    counter <= WIDTH;
+  end else begin
+    if (counter == 0) begin
+      started <= 0;
+      ssel <= 1;
+      ready <= 1;
+    end else begin
+      ssel <= 0;
+      ready <= 0;
+      mosi <= sp_in[WIDTH-1];
+      sp_in <= sp_in << 1;
+      sp_out <= (sp_out << 1) | miso;
+      counter <= counter - 1;
+    end
+  end
+end else begin
+  ssel <= 1;
+  ready <= 1;
+end
+
+endmodule
\ No newline at end of file
diff --git a/top.v b/top.v
new file mode 100644 (file)
index 0000000..a3bea87
--- /dev/null
+++ b/top.v
@@ -0,0 +1,134 @@
+module top(
+  clkpin,
+  button,
+  led
+);
+
+input clkpin;
+input button;
+output [3:0] led;
+
+wire clk;    // 300MHz
+wire spiclk; // 20MHz
+wire tftclk; // 6.667MHz
+
+clocks clocks_instance(
+  .clkpin(clkpin),
+  .rst(1'b0),
+  .clk(clk),
+  .spiclk(spiclk),
+  .tftclk(tftclk)
+);
+
+reg slowclk; // 1Hz
+reg [31:0] counter = 0;
+wire [23:0] spi_in;
+wire [23:0] spi_out;
+wire spi_ready;
+reg spi_enable = 0;
+wire mosi;
+wire ssel;
+
+assign led[0] = slowclk;
+assign led[1] = ssel;
+assign led[2] = mosi;
+assign led[3] = spi_ready;
+
+master_spi #(
+  .WIDTH(24)
+)
+master_spi_instance (
+  .clk(slowclk),
+  .mosi(mosi),
+  .miso(1'b0),
+  .ssel(ssel),
+  .din(spi_in),
+  .dout(spi_out),
+  .ready(spi_ready),
+  .enable(spi_enable)
+);
+
+reg [1:0] state = 0;
+reg [5:0] index = 0;
+
+reg [23:0] init_sequence [0:45];
+
+initial begin
+  init_sequence[ 0] = 24'h700001;
+  init_sequence[ 1] = 24'h726300;
+  init_sequence[ 2] = 24'h700002;
+  init_sequence[ 3] = 24'h720200;
+  init_sequence[ 4] = 24'h700003;
+  init_sequence[ 5] = 24'h726064;
+  init_sequence[ 6] = 24'h700004;
+  init_sequence[ 7] = 24'h720447;
+  init_sequence[ 8] = 24'h700005;
+  init_sequence[ 9] = 24'h72b084;
+  init_sequence[10] = 24'h70000a;
+  init_sequence[11] = 24'h724008;
+  init_sequence[12] = 24'h70000b;
+  init_sequence[13] = 24'h72d400;
+  init_sequence[14] = 24'h70000d;
+  init_sequence[15] = 24'h72423d;
+  init_sequence[16] = 24'h70000e;
+  init_sequence[17] = 24'h723140;
+  init_sequence[18] = 24'h70000f;
+  init_sequence[19] = 24'h720000;
+  init_sequence[20] = 24'h700016;
+  init_sequence[21] = 24'h729f80;
+  init_sequence[22] = 24'h700017;
+  init_sequence[23] = 24'h722212;
+  init_sequence[24] = 24'h70001e;
+  init_sequence[25] = 24'h7200db;
+  init_sequence[26] = 24'h700030;
+  init_sequence[27] = 24'h720000;
+  init_sequence[28] = 24'h700031;
+  init_sequence[29] = 24'h720607;
+  init_sequence[30] = 24'h700032;
+  init_sequence[31] = 24'h720006;
+  init_sequence[32] = 24'h700033;
+  init_sequence[33] = 24'h720307;
+  init_sequence[34] = 24'h700034;
+  init_sequence[35] = 24'h720107;
+  init_sequence[36] = 24'h700035;
+  init_sequence[37] = 24'h720001;
+  init_sequence[38] = 24'h700036;
+  init_sequence[39] = 24'h720707;
+  init_sequence[40] = 24'h700037;
+  init_sequence[41] = 24'h720703;
+  init_sequence[42] = 24'h70003a;
+  init_sequence[43] = 24'h720c00;
+  init_sequence[44] = 24'h70003b;
+  init_sequence[45] = 24'h720006;
+end
+
+assign spi_in = init_sequence[index];
+
+reg [1:0] button_state = 0;
+always @(posedge clk) begin
+  if (button_state == 2'b10) state <= 1;
+  button_state <= {button_state[0], button};
+end
+
+always @(posedge slowclk) begin
+  case(state)
+    1: begin state <= 2; index <= 0; end
+    2: if (spi_ready) spi_enable <= 1;
+    3: if (spi_ready) begin
+          spi_enable <= 0;
+          state <= index == 45 ? 0 : 2;
+          index <= index + 1;
+    end
+  endcase
+end
+
+always @(posedge clk) begin
+  if (counter == 150000000) begin
+    counter <= 0;
+        slowclk <= ~slowclk;
+  end else begin
+    counter <= counter + 1;     
+  end
+end
+
+endmodule