Externalize CRG into its own file
[gram.git] / gram / simulation / simsoctb.v
index 84d7c866e90620c892ddf9f379b3600701403113..a8d3c8d3f3c743197f459e0da339e7f16513fab6 100644 (file)
@@ -1,8 +1,11 @@
 // This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
 
-`timescale 1 ns / 1 ps
+`timescale 1 ns / 1 ns
 
 module simsoctb;
+  //parameter simticks = 70000;
+  parameter simticks = 60000000;
+
   // GSR & PUR init requires for Lattice models
   GSR GSR_INST (
     .GSR(1'b1)
@@ -27,7 +30,7 @@ module simsoctb;
   end
 
   // UART
-  wire uart_rx;
+  reg uart_rx;
   wire uart_tx;
 
   // DDR3 init
@@ -48,7 +51,7 @@ module simsoctb;
   ddr3 ram_chip (
     .rst_n(1'b1),
     .ck(dram_ck),
-    .ck_n(dram_ck_n),
+    .ck_n(1'b0),
     .cke(dram_cke),
     .cs_n(1'b0),
     .ras_n(dram_ras_n),
@@ -83,24 +86,152 @@ module simsoctb;
   );
 
   initial
-  begin
-    $dumpfile("simsoc.fst");
-    $dumpvars(0, clkin);
-    $dumpvars(0, dram_dq);
-    $dumpvars(0, dram_dqs);
-    $dumpvars(0, dram_ck);
-    $dumpvars(0, dram_cke);
-    $dumpvars(0, dram_we_n);
-    $dumpvars(0, dram_ras_n);
-    $dumpvars(0, dram_cas_n);
-    $dumpvars(0, dram_a);
-    $dumpvars(0, dram_ba);
-    $dumpvars(0, dram_dm);
-    $dumpvars(0, dram_odt);
-    $dumpvars(0, uart_rx);
-    $dumpvars(0, uart_tx);
-    $dumpvars(0, simsoctop);
-
-    #10000 $finish;
-  end
+    begin
+      $dumpfile("simsoc.fst");
+      $dumpvars(0, clkin);
+      $dumpvars(0, dram_dq);
+      $dumpvars(0, dram_dqs);
+      $dumpvars(0, dram_ck);
+      $dumpvars(0, dram_cke);
+      $dumpvars(0, dram_we_n);
+      $dumpvars(0, dram_ras_n);
+      $dumpvars(0, dram_cas_n);
+      $dumpvars(0, dram_a);
+      $dumpvars(0, dram_ba);
+      $dumpvars(0, dram_dm);
+      $dumpvars(0, dram_odt);
+      $dumpvars(0, uart_rx);
+      $dumpvars(0, uart_tx);
+      $dumpvars(0, simsoctop);
+
+      #simticks $finish;
+    end
+
+  // UART
+  reg [31:0] tmp;
+  initial
+    begin
+      uart_rx <= 1'b1;
+      #700000; // POR is ~700us
+
+      // Software control
+      wishbone_write(32'h00009000 >> 2, 8'h0E); // DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE
+
+      wishbone_write(32'h0000900c >> 2, 32'h0); // p0 address
+      wishbone_write(32'h00009010 >> 2, 32'h0); // p0 baddress
+      wishbone_write(32'h00009000 >> 2, 8'h0C); // DFII_CONTROL_ODT|DFII_CONTROL_RESET_N
+      #500000;
+      wishbone_write(32'h00009000 >> 2, 8'h0E); // DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE
+      #500000;
+
+      // Set MR2
+      wishbone_write(32'h0000900c >> 2, 32'h200); // p0 address
+      wishbone_write(32'h00009010 >> 2, 32'h2); // p0 baddress
+      wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
+      wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
+
+      // Set MR3
+      wishbone_write(32'h0000900c >> 2, 32'h0); // p0 address
+      wishbone_write(32'h00009010 >> 2, 32'h3); // p0 baddress
+      wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
+      wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
+
+      // Set MR1
+      wishbone_write(32'h0000900c >> 2, 32'h6); // p0 address
+      wishbone_write(32'h00009010 >> 2, 32'h1); // p0 baddress
+      wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
+      wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
+
+      // Set MR0
+      wishbone_write(32'h0000900c >> 2, 32'h320); // p0 address
+      wishbone_write(32'h00009010 >> 2, 32'h0); // p0 baddress
+      wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
+      wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
+      #2000;
+
+      // ZQ calibration
+      wishbone_write(32'h0000900c >> 2, 32'h400); // p0 address
+      wishbone_write(32'h00009010 >> 2, 32'h0); // p0 baddress
+      wishbone_write(32'h00009004 >> 2, 8'h03); // WE|CS
+      wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
+      #2000;
+
+      // Hardware control
+      wishbone_write(32'h00009000 >> 2, 8'h01); // DFII_CONTROL_SEL
+      #2000;
+
+      wishbone_read(32'h10000000 >> 2, tmp);
+    end
+
+  task wishbone_write;
+    input [31:0] address;
+    input [31:0] value;
+
+    begin
+      uart_send(8'h01); // Write command
+      uart_send(8'h01); // Length
+      uart_send(address[31:24]); // Address
+      uart_send(address[23:16]);
+      uart_send(address[15:8]);
+      uart_send(address[7:0]);
+      uart_send(value[31:24]);
+      uart_send(value[23:16]);
+      uart_send(value[15:8]);
+      uart_send(value[7:0]);
+    end
+  endtask
+
+  task wishbone_read;
+    input [31:0] address;
+    output [31:0] value;
+
+    begin
+      uart_send(8'h02); // Read command
+      uart_send(8'h01); // Length
+      uart_send(address[31:24]); // Address
+      uart_send(address[23:16]);
+      uart_send(address[15:8]);
+      uart_send(address[7:0]);
+      uart_read(value[31:24]);
+      uart_read(value[23:16]);
+      uart_read(value[15:8]);
+      uart_read(value[7:0]);
+    end
+  endtask
+
+  task uart_send;
+    input [7:0] data;
+    integer i;
+
+    begin
+      uart_rx <= 1'b0;
+      #8680;
+      for (i = 0; i < 8; i = i + 1)
+        begin
+          uart_rx <= data[i];
+          #8680;
+        end
+      uart_rx <= 1'b1;
+      #8680;
+    end
+  endtask
+
+  task uart_read;
+    output [7:0] data;
+    integer i;
+
+    begin
+      while (uart_tx)
+        begin
+          #1;
+        end
+
+      for (i = 0; i < 8; i = i+1)
+        begin
+          #8680 data[i] <= uart_tx;
+        end
+
+      #8680;
+    end
+  endtask
 endmodule