Externalize CRG into its own file
[gram.git] / gram / simulation / simsoctb.v
1 // This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
2
3 `timescale 1 ns / 1 ns
4
5 module simsoctb;
6 //parameter simticks = 70000;
7 parameter simticks = 60000000;
8
9 // GSR & PUR init requires for Lattice models
10 GSR GSR_INST (
11 .GSR(1'b1)
12 );
13 PUR PUR_INST (
14 .PUR (1'b1)
15 );
16
17 reg clkin;
18 wire sync;
19 wire sync2x;
20 wire dramsync;
21 wire init;
22
23 // Generate 100 Mhz clock
24 always
25 begin
26 clkin = 1'b1;
27 #5;
28 clkin = 1'b0;
29 #5;
30 end
31
32 // UART
33 reg uart_rx;
34 wire uart_tx;
35
36 // DDR3 init
37 wire dram_ck;
38 wire dram_cke;
39 wire dram_we_n;
40 wire dram_ras_n;
41 wire dram_cas_n;
42 wire [15:0] dram_dq;
43 wire [1:0] dram_dqs;
44 wire [1:0] dram_dqs_n;
45 wire [13:0] dram_a;
46 wire [2:0] dram_ba;
47 wire [1:0] dram_dm;
48 wire dram_odt;
49 wire [1:0] dram_tdqs_n;
50
51 ddr3 ram_chip (
52 .rst_n(1'b1),
53 .ck(dram_ck),
54 .ck_n(1'b0),
55 .cke(dram_cke),
56 .cs_n(1'b0),
57 .ras_n(dram_ras_n),
58 .cas_n(dram_cas_n),
59 .we_n(dram_we_n),
60 .dm_tdqs(dram_dm),
61 .ba(dram_ba),
62 .addr(dram_a),
63 .dq(dram_dq),
64 .dqs(dram_dqs),
65 .dqs_n(dram_dqs_n),
66 .tdqs_n(dram_tdqs_n),
67 .odt(dram_odt)
68 );
69
70 top simsoctop (
71 .ddr3_0__dq__io(dram_dq),
72 .ddr3_0__dqs__io(dram_dqs),
73 .ddr3_0__clk__io(dram_ck),
74 .ddr3_0__cke__io(dram_cke),
75 .ddr3_0__we_n__io(dram_we_n),
76 .ddr3_0__ras_n__io(dram_ras_n),
77 .ddr3_0__cas_n__io(dram_cas_n),
78 .ddr3_0__a__io(dram_a),
79 .ddr3_0__ba__io(dram_ba),
80 .ddr3_0__dm__io(dram_dm),
81 .ddr3_0__odt__io(dram_odt),
82 .clk100_0__io(clkin),
83 .rst_0__io(1'b0),
84 .uart_0__rx__io(uart_rx),
85 .uart_0__tx__io(uart_tx)
86 );
87
88 initial
89 begin
90 $dumpfile("simsoc.fst");
91 $dumpvars(0, clkin);
92 $dumpvars(0, dram_dq);
93 $dumpvars(0, dram_dqs);
94 $dumpvars(0, dram_ck);
95 $dumpvars(0, dram_cke);
96 $dumpvars(0, dram_we_n);
97 $dumpvars(0, dram_ras_n);
98 $dumpvars(0, dram_cas_n);
99 $dumpvars(0, dram_a);
100 $dumpvars(0, dram_ba);
101 $dumpvars(0, dram_dm);
102 $dumpvars(0, dram_odt);
103 $dumpvars(0, uart_rx);
104 $dumpvars(0, uart_tx);
105 $dumpvars(0, simsoctop);
106
107 #simticks $finish;
108 end
109
110 // UART
111 reg [31:0] tmp;
112 initial
113 begin
114 uart_rx <= 1'b1;
115 #700000; // POR is ~700us
116
117 // Software control
118 wishbone_write(32'h00009000 >> 2, 8'h0E); // DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE
119
120 wishbone_write(32'h0000900c >> 2, 32'h0); // p0 address
121 wishbone_write(32'h00009010 >> 2, 32'h0); // p0 baddress
122 wishbone_write(32'h00009000 >> 2, 8'h0C); // DFII_CONTROL_ODT|DFII_CONTROL_RESET_N
123 #500000;
124 wishbone_write(32'h00009000 >> 2, 8'h0E); // DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE
125 #500000;
126
127 // Set MR2
128 wishbone_write(32'h0000900c >> 2, 32'h200); // p0 address
129 wishbone_write(32'h00009010 >> 2, 32'h2); // p0 baddress
130 wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
131 wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
132
133 // Set MR3
134 wishbone_write(32'h0000900c >> 2, 32'h0); // p0 address
135 wishbone_write(32'h00009010 >> 2, 32'h3); // p0 baddress
136 wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
137 wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
138
139 // Set MR1
140 wishbone_write(32'h0000900c >> 2, 32'h6); // p0 address
141 wishbone_write(32'h00009010 >> 2, 32'h1); // p0 baddress
142 wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
143 wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
144
145 // Set MR0
146 wishbone_write(32'h0000900c >> 2, 32'h320); // p0 address
147 wishbone_write(32'h00009010 >> 2, 32'h0); // p0 baddress
148 wishbone_write(32'h00009004 >> 2, 8'h0F); // RAS|CAS|WE|CS
149 wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
150 #2000;
151
152 // ZQ calibration
153 wishbone_write(32'h0000900c >> 2, 32'h400); // p0 address
154 wishbone_write(32'h00009010 >> 2, 32'h0); // p0 baddress
155 wishbone_write(32'h00009004 >> 2, 8'h03); // WE|CS
156 wishbone_write(32'h00009008 >> 2, 8'h01); // Command issue strobe
157 #2000;
158
159 // Hardware control
160 wishbone_write(32'h00009000 >> 2, 8'h01); // DFII_CONTROL_SEL
161 #2000;
162
163 wishbone_read(32'h10000000 >> 2, tmp);
164 end
165
166 task wishbone_write;
167 input [31:0] address;
168 input [31:0] value;
169
170 begin
171 uart_send(8'h01); // Write command
172 uart_send(8'h01); // Length
173 uart_send(address[31:24]); // Address
174 uart_send(address[23:16]);
175 uart_send(address[15:8]);
176 uart_send(address[7:0]);
177 uart_send(value[31:24]);
178 uart_send(value[23:16]);
179 uart_send(value[15:8]);
180 uart_send(value[7:0]);
181 end
182 endtask
183
184 task wishbone_read;
185 input [31:0] address;
186 output [31:0] value;
187
188 begin
189 uart_send(8'h02); // Read command
190 uart_send(8'h01); // Length
191 uart_send(address[31:24]); // Address
192 uart_send(address[23:16]);
193 uart_send(address[15:8]);
194 uart_send(address[7:0]);
195 uart_read(value[31:24]);
196 uart_read(value[23:16]);
197 uart_read(value[15:8]);
198 uart_read(value[7:0]);
199 end
200 endtask
201
202 task uart_send;
203 input [7:0] data;
204 integer i;
205
206 begin
207 uart_rx <= 1'b0;
208 #8680;
209 for (i = 0; i < 8; i = i + 1)
210 begin
211 uart_rx <= data[i];
212 #8680;
213 end
214 uart_rx <= 1'b1;
215 #8680;
216 end
217 endtask
218
219 task uart_read;
220 output [7:0] data;
221 integer i;
222
223 begin
224 while (uart_tx)
225 begin
226 #1;
227 end
228
229 for (i = 0; i < 8; i = i+1)
230 begin
231 #8680 data[i] <= uart_tx;
232 end
233
234 #8680;
235 end
236 endtask
237 endmodule