diff --git a/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/coarserom.v b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/coarserom.v new file mode 100644 index 0000000..d5550af --- /dev/null +++ b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/coarserom.v @@ -0,0 +1,26 @@ + + +module coarserom ( + address, + clock, + q); + + parameter init_file = "missing.txt"; + + input [7:0] address; + input clock; + output reg [35:0] q; + + reg [35:0] rom[255:0]; + + initial + begin + $readmemb(init_file, rom); + end + + always @ (posedge clock) + begin + q <= rom[address]; + end + +endmodule diff --git a/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/finerom.v b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/finerom.v new file mode 100644 index 0000000..da00831 --- /dev/null +++ b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/finerom.v @@ -0,0 +1,26 @@ + + +module finerom ( + address, + clock, + q); + + parameter init_file = "missing.txt"; + + input [8:0] address; + input clock; + output reg [8:0] q; + + reg [8:0] rom[511:0]; + + initial + begin + $readmemb(init_file, rom); + end + + always @ (posedge clock) + begin + q <= rom[address]; + end + +endmodule diff --git a/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/mix1.v b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/mix1.v new file mode 100644 index 0000000..b5a0392 --- /dev/null +++ b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/mix1.v @@ -0,0 +1,53 @@ + +`timescale 1us/1ns + +module mix1 ( + clk, + rst, + phi, + adc, + i_data, + q_data +); + +input clk; +input rst; +input [31:0] phi; +input signed [11:0] adc; +output signed [17:0] i_data; +output signed [17:0] q_data; + +logic [18:0] sin, ssin; +logic [18:0] cos, scos; + +logic signed [17:0] ssin_q, scos_q; +logic signed [35:0] i_data_d, q_data_d; + +nco1 #(.CALCTYPE(3)) nco1_i ( + .clk(clk), + .rst(rst), + .phi(phi), + .cos(cos), + .sin(sin) +); + +assign ssin = {sin[18],~sin[17:0]} + 19'h01; +assign scos = {cos[18],~cos[17:0]} + 19'h01; + +always @(posedge clk) begin + ssin_q <= sin[18] ? ssin[18:1] : sin[18:1]; + scos_q <= cos[18] ? scos[18:1] : cos[18:1]; +end + + +always @(posedge clk) begin + i_data_d <= $signed(adc) * scos_q; + q_data_d <= $signed(adc) * ssin_q; +end + +assign i_data = i_data_d[28:11]; +assign q_data = q_data_d[28:11]; + +endmodule + + diff --git a/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/mix2.v b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/mix2.v new file mode 100644 index 0000000..d6f1047 --- /dev/null +++ b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/mix2.v @@ -0,0 +1,85 @@ + +`timescale 1us/1ns + +module mix2 ( + clk, + clk_2x, + rst, + phi0, + phi1, + adc, + mixdata0_i, + mixdata0_q, + mixdata1_i, + mixdata1_q +); + +input clk; +input clk_2x; +input rst; +input [31:0] phi0; +input [31:0] phi1; +input signed [11:0] adc; +output signed [17:0] mixdata0_i; +output signed [17:0] mixdata0_q; +output signed [17:0] mixdata1_i; +output signed [17:0] mixdata1_q; + +parameter CALCTYPE = 0; + +logic [18:0] sin, ssin; +logic [18:0] cos, scos; + +logic signed [17:0] ssin_q, scos_q; +logic signed [35:0] i_data_d, q_data_d; + +logic signed [11:0] adci, adcq; + +logic state = 1'b0; + + +nco2 #(.CALCTYPE(CALCTYPE)) nco2_i ( + .state(state), + .clk_2x(clk_2x), + .rst(rst), + .phi0(phi0), + .phi1(phi1), + .cos(cos), + .sin(sin) +); + +always @(posedge clk_2x) begin + state <= ~state; +end + +assign ssin = {sin[18],~sin[17:0]} + 19'h01; +assign scos = {cos[18],~cos[17:0]} + 19'h01; + +always @(posedge clk_2x) begin + ssin_q <= sin[18] ? ssin[18:1] : sin[18:1]; + scos_q <= cos[18] ? scos[18:1] : cos[18:1]; +end + +always @(posedge clk_2x) begin + adci <= adc; + adcq <= adc; +end + +always @(posedge clk_2x) begin + i_data_d <= $signed(adci) * scos_q; + q_data_d <= $signed(adcq) * ssin_q; +end + +always @(posedge clk_2x) begin + if (~state) begin + mixdata0_i <= i_data_d[28:11]; + mixdata0_q <= q_data_d[28:11]; + end else begin + mixdata1_i <= i_data_d[28:11]; + mixdata1_q <= q_data_d[28:11]; + end +end + +endmodule + + diff --git a/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/nco1.v b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/nco1.v new file mode 100644 index 0000000..7ab9f63 --- /dev/null +++ b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/nco1.v @@ -0,0 +1,37 @@ + +`timescale 1us/1ns + +module nco1 ( + clk, + rst, + phi, + cos, + sin +); + +input clk; +input rst; +input [31:0] phi; +output [18:0] sin; +output [18:0] cos; + +logic [31:0] angle = 32'h00; + +parameter CALCTYPE = 0; + +always @(posedge clk) begin + if (rst) angle <= 32'h00; + else angle <= angle + phi; +end + + +sincos #(.CALCTYPE(CALCTYPE)) sincos_i ( + .clk(clk), + .angle(angle[31:12]), + .cos(cos), + .sin(sin) +); + +endmodule + + diff --git a/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/nco2.v b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/nco2.v new file mode 100644 index 0000000..3e6cf7a --- /dev/null +++ b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/nco2.v @@ -0,0 +1,48 @@ + +`timescale 1us/1ns + +module nco2 ( + state, + clk_2x, + rst, + phi0, + phi1, + cos, + sin, +); + +input state; +input clk_2x; +input rst; +input [31:0] phi0; +input [31:0] phi1; +output [18:0] sin; +output [18:0] cos; + +logic [31:0] angle0 = 32'h00; +logic [31:0] angle1 = 32'h00; + +parameter CALCTYPE = 0; + + +always @(posedge clk_2x) begin + if (rst) begin + angle0 <= 32'h00; + angle1 <= 32'h00; + end else begin + angle1 <= angle0 + (state ? phi1 : phi0); + angle0 <= angle1; + end +end + + +sincos #(.CALCTYPE(CALCTYPE)) sincos_i ( + .clk(clk_2x), + .angle(angle1[31:12]), + .cos(cos), + .sin(sin) +); + +endmodule + + diff --git a/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/sin_fine.txt b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/sin_fine.txt new file mode 100644 index 0000000..0c9501b --- /dev/null +++ b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/sin_fine.txt @@ -0,0 +1,512 @@ +000000000 // 0 0x1 +000000001 // 1 0x2 +000000010 // 2 0x4 +000000011 // 3 0x5 +000000100 // 4 0x7 +000000100 // 5 0x9 +000000101 // 6 0xa +000000110 // 7 0xc +000000111 // 8 0xd +000000111 // 9 0xf +000001000 // 10 0x10 +000001001 // 11 0x12 +000001010 // 12 0x14 +000001011 // 13 0x15 +000001011 // 14 0x17 +000001100 // 15 0x18 +000001101 // 16 0x1a +000001110 // 17 0x1b +000001111 // 18 0x1d +000001111 // 19 0x1f +000010000 // 20 0x20 +000010001 // 21 0x22 +000010010 // 22 0x23 +000010010 // 23 0x25 +000010011 // 24 0x26 +000010100 // 25 0x28 +000010101 // 26 0x2a +000010110 // 27 0x2b +000010110 // 28 0x2d +000010111 // 29 0x2e +000011000 // 30 0x30 +000011001 // 31 0x31 +000011010 // 32 0x33 +000011010 // 33 0x35 +000011011 // 34 0x36 +000011100 // 35 0x38 +000011101 // 36 0x39 +000011101 // 37 0x3b +000011110 // 38 0x3c +000011111 // 39 0x3e +000100000 // 40 0x40 +000100001 // 41 0x41 +000100001 // 42 0x43 +000100010 // 43 0x44 +000100011 // 44 0x46 +000100100 // 45 0x47 +000100101 // 46 0x49 +000100101 // 47 0x4b +000100110 // 48 0x4c +000100111 // 49 0x4e +000101000 // 50 0x4f +000101000 // 51 0x51 +000101001 // 52 0x52 +000101010 // 53 0x54 +000101011 // 54 0x56 +000101100 // 55 0x57 +000101100 // 56 0x59 +000101101 // 57 0x5a +000101110 // 58 0x5c +000101111 // 59 0x5d +000110000 // 60 0x5f +000110000 // 61 0x61 +000110001 // 62 0x62 +000110010 // 63 0x64 +000110011 // 64 0x65 +000110011 // 65 0x67 +000110100 // 66 0x68 +000110101 // 67 0x6a +000110110 // 68 0x6c +000110111 // 69 0x6d +000110111 // 70 0x6f +000111000 // 71 0x70 +000111001 // 72 0x72 +000111010 // 73 0x73 +000111011 // 74 0x75 +000111011 // 75 0x77 +000111100 // 76 0x78 +000111101 // 77 0x7a +000111110 // 78 0x7b +000111110 // 79 0x7d +000111111 // 80 0x7e +001000000 // 81 0x80 +001000001 // 82 0x82 +001000010 // 83 0x83 +001000010 // 84 0x85 +001000011 // 85 0x86 +001000100 // 86 0x88 +001000101 // 87 0x89 +001000110 // 88 0x8b +001000110 // 89 0x8d +001000111 // 90 0x8e +001001000 // 91 0x90 +001001001 // 92 0x91 +001001001 // 93 0x93 +001001010 // 94 0x94 +001001011 // 95 0x96 +001001100 // 96 0x98 +001001101 // 97 0x99 +001001101 // 98 0x9b +001001110 // 99 0x9c +001001111 // 100 0x9e +001010000 // 101 0x9f +001010001 // 102 0xa1 +001010001 // 103 0xa3 +001010010 // 104 0xa4 +001010011 // 105 0xa6 +001010100 // 106 0xa7 +001010100 // 107 0xa9 +001010101 // 108 0xaa +001010110 // 109 0xac +001010111 // 110 0xae +001011000 // 111 0xaf +001011000 // 112 0xb1 +001011001 // 113 0xb2 +001011010 // 114 0xb4 +001011011 // 115 0xb5 +001011011 // 116 0xb7 +001011100 // 117 0xb9 +001011101 // 118 0xba +001011110 // 119 0xbc +001011111 // 120 0xbd +001011111 // 121 0xbf +001100000 // 122 0xc0 +001100001 // 123 0xc2 +001100010 // 124 0xc4 +001100011 // 125 0xc5 +001100011 // 126 0xc7 +001100100 // 127 0xc8 +001100101 // 128 0xca +001100110 // 129 0xcb +001100110 // 130 0xcd +001100111 // 131 0xcf +001101000 // 132 0xd0 +001101001 // 133 0xd2 +001101010 // 134 0xd3 +001101010 // 135 0xd5 +001101011 // 136 0xd6 +001101100 // 137 0xd8 +001101101 // 138 0xda +001101110 // 139 0xdb +001101110 // 140 0xdd +001101111 // 141 0xde +001110000 // 142 0xe0 +001110001 // 143 0xe1 +001110001 // 144 0xe3 +001110010 // 145 0xe5 +001110011 // 146 0xe6 +001110100 // 147 0xe8 +001110101 // 148 0xe9 +001110101 // 149 0xeb +001110110 // 150 0xec +001110111 // 151 0xee +001111000 // 152 0xf0 +001111001 // 153 0xf1 +001111001 // 154 0xf3 +001111010 // 155 0xf4 +001111011 // 156 0xf6 +001111100 // 157 0xf7 +001111100 // 158 0xf9 +001111101 // 159 0xfb +001111110 // 160 0xfc +001111111 // 161 0xfe +010000000 // 162 0xff +010000000 // 163 0x101 +010000001 // 164 0x102 +010000010 // 165 0x104 +010000011 // 166 0x106 +010000100 // 167 0x107 +010000100 // 168 0x109 +010000101 // 169 0x10a +010000110 // 170 0x10c +010000111 // 171 0x10d +010000111 // 172 0x10f +010001000 // 173 0x111 +010001001 // 174 0x112 +010001010 // 175 0x114 +010001011 // 176 0x115 +010001011 // 177 0x117 +010001100 // 178 0x118 +010001101 // 179 0x11a +010001110 // 180 0x11c +010001111 // 181 0x11d +010001111 // 182 0x11f +010010000 // 183 0x120 +010010001 // 184 0x122 +010010010 // 185 0x123 +010010010 // 186 0x125 +010010011 // 187 0x127 +010010100 // 188 0x128 +010010101 // 189 0x12a +010010110 // 190 0x12b +010010110 // 191 0x12d +010010111 // 192 0x12e +010011000 // 193 0x130 +010011001 // 194 0x132 +010011010 // 195 0x133 +010011010 // 196 0x135 +010011011 // 197 0x136 +010011100 // 198 0x138 +010011101 // 199 0x139 +010011101 // 200 0x13b +010011110 // 201 0x13d +010011111 // 202 0x13e +010100000 // 203 0x140 +010100001 // 204 0x141 +010100001 // 205 0x143 +010100010 // 206 0x144 +010100011 // 207 0x146 +010100100 // 208 0x148 +010100101 // 209 0x149 +010100101 // 210 0x14b +010100110 // 211 0x14c +010100111 // 212 0x14e +010101000 // 213 0x14f +010101000 // 214 0x151 +010101001 // 215 0x153 +010101010 // 216 0x154 +010101011 // 217 0x156 +010101100 // 218 0x157 +010101100 // 219 0x159 +010101101 // 220 0x15a +010101110 // 221 0x15c +010101111 // 222 0x15d +010110000 // 223 0x15f +010110000 // 224 0x161 +010110001 // 225 0x162 +010110010 // 226 0x164 +010110011 // 227 0x165 +010110011 // 228 0x167 +010110100 // 229 0x168 +010110101 // 230 0x16a +010110110 // 231 0x16c +010110111 // 232 0x16d +010110111 // 233 0x16f +010111000 // 234 0x170 +010111001 // 235 0x172 +010111010 // 236 0x173 +010111011 // 237 0x175 +010111011 // 238 0x177 +010111100 // 239 0x178 +010111101 // 240 0x17a +010111110 // 241 0x17b +010111110 // 242 0x17d +010111111 // 243 0x17e +011000000 // 244 0x180 +011000001 // 245 0x182 +011000010 // 246 0x183 +011000010 // 247 0x185 +011000011 // 248 0x186 +011000100 // 249 0x188 +011000101 // 250 0x189 +011000110 // 251 0x18b +011000110 // 252 0x18d +011000111 // 253 0x18e +011001000 // 254 0x190 +011001001 // 255 0x191 +011001001 // 256 0x193 +011001010 // 257 0x194 +011001011 // 258 0x196 +011001100 // 259 0x198 +011001101 // 260 0x199 +011001101 // 261 0x19b +011001110 // 262 0x19c +011001111 // 263 0x19e +011010000 // 264 0x19f +011010001 // 265 0x1a1 +011010001 // 266 0x1a3 +011010010 // 267 0x1a4 +011010011 // 268 0x1a6 +011010100 // 269 0x1a7 +011010100 // 270 0x1a9 +011010101 // 271 0x1aa +011010110 // 272 0x1ac +011010111 // 273 0x1ae +011011000 // 274 0x1af +011011000 // 275 0x1b1 +011011001 // 276 0x1b2 +011011010 // 277 0x1b4 +011011011 // 278 0x1b5 +011011100 // 279 0x1b7 +011011100 // 280 0x1b9 +011011101 // 281 0x1ba +011011110 // 282 0x1bc +011011111 // 283 0x1bd +011011111 // 284 0x1bf +011100000 // 285 0x1c0 +011100001 // 286 0x1c2 +011100010 // 287 0x1c4 +011100011 // 288 0x1c5 +011100011 // 289 0x1c7 +011100100 // 290 0x1c8 +011100101 // 291 0x1ca +011100110 // 292 0x1cb +011100111 // 293 0x1cd +011100111 // 294 0x1cf +011101000 // 295 0x1d0 +011101001 // 296 0x1d2 +011101010 // 297 0x1d3 +011101010 // 298 0x1d5 +011101011 // 299 0x1d6 +011101100 // 300 0x1d8 +011101101 // 301 0x1da +011101110 // 302 0x1db +011101110 // 303 0x1dd +011101111 // 304 0x1de +011110000 // 305 0x1e0 +011110001 // 306 0x1e1 +011110010 // 307 0x1e3 +011110010 // 308 0x1e5 +011110011 // 309 0x1e6 +011110100 // 310 0x1e8 +011110101 // 311 0x1e9 +011110101 // 312 0x1eb +011110110 // 313 0x1ec +011110111 // 314 0x1ee +011111000 // 315 0x1f0 +011111001 // 316 0x1f1 +011111001 // 317 0x1f3 +011111010 // 318 0x1f4 +011111011 // 319 0x1f6 +011111100 // 320 0x1f7 +011111101 // 321 0x1f9 +011111101 // 322 0x1fb +011111110 // 323 0x1fc +011111111 // 324 0x1fe +100000000 // 325 0x1ff +100000000 // 326 0x201 +100000001 // 327 0x202 +100000010 // 328 0x204 +100000011 // 329 0x206 +100000100 // 330 0x207 +100000100 // 331 0x209 +100000101 // 332 0x20a +100000110 // 333 0x20c +100000111 // 334 0x20d +100000111 // 335 0x20f +100001000 // 336 0x211 +100001001 // 337 0x212 +100001010 // 338 0x214 +100001011 // 339 0x215 +100001011 // 340 0x217 +100001100 // 341 0x218 +100001101 // 342 0x21a +100001110 // 343 0x21c +100001111 // 344 0x21d +100001111 // 345 0x21f +100010000 // 346 0x220 +100010001 // 347 0x222 +100010010 // 348 0x223 +100010010 // 349 0x225 +100010011 // 350 0x227 +100010100 // 351 0x228 +100010101 // 352 0x22a +100010110 // 353 0x22b +100010110 // 354 0x22d +100010111 // 355 0x22e +100011000 // 356 0x230 +100011001 // 357 0x232 +100011010 // 358 0x233 +100011010 // 359 0x235 +100011011 // 360 0x236 +100011100 // 361 0x238 +100011101 // 362 0x239 +100011101 // 363 0x23b +100011110 // 364 0x23d +100011111 // 365 0x23e +100100000 // 366 0x240 +100100001 // 367 0x241 +100100001 // 368 0x243 +100100010 // 369 0x244 +100100011 // 370 0x246 +100100100 // 371 0x248 +100100101 // 372 0x249 +100100101 // 373 0x24b +100100110 // 374 0x24c +100100111 // 375 0x24e +100101000 // 376 0x24f +100101000 // 377 0x251 +100101001 // 378 0x253 +100101010 // 379 0x254 +100101011 // 380 0x256 +100101100 // 381 0x257 +100101100 // 382 0x259 +100101101 // 383 0x25a +100101110 // 384 0x25c +100101111 // 385 0x25e +100110000 // 386 0x25f +100110000 // 387 0x261 +100110001 // 388 0x262 +100110010 // 389 0x264 +100110011 // 390 0x265 +100110011 // 391 0x267 +100110100 // 392 0x269 +100110101 // 393 0x26a +100110110 // 394 0x26c +100110111 // 395 0x26d +100110111 // 396 0x26f +100111000 // 397 0x270 +100111001 // 398 0x272 +100111010 // 399 0x274 +100111011 // 400 0x275 +100111011 // 401 0x277 +100111100 // 402 0x278 +100111101 // 403 0x27a +100111110 // 404 0x27b +100111110 // 405 0x27d +100111111 // 406 0x27f +101000000 // 407 0x280 +101000001 // 408 0x282 +101000010 // 409 0x283 +101000010 // 410 0x285 +101000011 // 411 0x286 +101000100 // 412 0x288 +101000101 // 413 0x28a +101000110 // 414 0x28b +101000110 // 415 0x28d +101000111 // 416 0x28e +101001000 // 417 0x290 +101001001 // 418 0x291 +101001001 // 419 0x293 +101001010 // 420 0x295 +101001011 // 421 0x296 +101001100 // 422 0x298 +101001101 // 423 0x299 +101001101 // 424 0x29b +101001110 // 425 0x29c +101001111 // 426 0x29e +101010000 // 427 0x2a0 +101010001 // 428 0x2a1 +101010001 // 429 0x2a3 +101010010 // 430 0x2a4 +101010011 // 431 0x2a6 +101010100 // 432 0x2a7 +101010100 // 433 0x2a9 +101010101 // 434 0x2ab +101010110 // 435 0x2ac +101010111 // 436 0x2ae +101011000 // 437 0x2af +101011000 // 438 0x2b1 +101011001 // 439 0x2b2 +101011010 // 440 0x2b4 +101011011 // 441 0x2b6 +101011100 // 442 0x2b7 +101011100 // 443 0x2b9 +101011101 // 444 0x2ba +101011110 // 445 0x2bc +101011111 // 446 0x2bd +101011111 // 447 0x2bf +101100000 // 448 0x2c0 +101100001 // 449 0x2c2 +101100010 // 450 0x2c4 +101100011 // 451 0x2c5 +101100011 // 452 0x2c7 +101100100 // 453 0x2c8 +101100101 // 454 0x2ca +101100110 // 455 0x2cb +101100111 // 456 0x2cd +101100111 // 457 0x2cf +101101000 // 458 0x2d0 +101101001 // 459 0x2d2 +101101010 // 460 0x2d3 +101101010 // 461 0x2d5 +101101011 // 462 0x2d6 +101101100 // 463 0x2d8 +101101101 // 464 0x2da +101101110 // 465 0x2db +101101110 // 466 0x2dd +101101111 // 467 0x2de +101110000 // 468 0x2e0 +101110001 // 469 0x2e1 +101110010 // 470 0x2e3 +101110010 // 471 0x2e5 +101110011 // 472 0x2e6 +101110100 // 473 0x2e8 +101110101 // 474 0x2e9 +101110101 // 475 0x2eb +101110110 // 476 0x2ec +101110111 // 477 0x2ee +101111000 // 478 0x2f0 +101111001 // 479 0x2f1 +101111001 // 480 0x2f3 +101111010 // 481 0x2f4 +101111011 // 482 0x2f6 +101111100 // 483 0x2f7 +101111101 // 484 0x2f9 +101111101 // 485 0x2fb +101111110 // 486 0x2fc +101111111 // 487 0x2fe +110000000 // 488 0x2ff +110000000 // 489 0x301 +110000001 // 490 0x302 +110000010 // 491 0x304 +110000011 // 492 0x306 +110000100 // 493 0x307 +110000100 // 494 0x309 +110000101 // 495 0x30a +110000110 // 496 0x30c +110000111 // 497 0x30d +110001000 // 498 0x30f +110001000 // 499 0x311 +110001001 // 500 0x312 +110001010 // 501 0x314 +110001011 // 502 0x315 +110001011 // 503 0x317 +110001100 // 504 0x318 +110001101 // 505 0x31a +110001110 // 506 0x31c +110001111 // 507 0x31d +110001111 // 508 0x31f +110010000 // 509 0x320 +110010001 // 510 0x322 +110010010 // 511 0x323 diff --git a/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/sincos.v b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/sincos.v new file mode 100644 index 0000000..5a5149f --- /dev/null +++ b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/sincos.v @@ -0,0 +1,280 @@ + +`timescale 1us/1ns + +module sincos ( + clk, + angle, + cos, + sin +); + +parameter CALCTYPE = 0; + +input clk; +input [19:0] angle; +output logic [18:0] sin; +output logic [18:0] cos; + +//Pipestage 1 +logic [7:0] coarse; +logic [9:0] fine; +logic [1:0] quadrant; +assign {quadrant,coarse,fine} = angle; + +logic [7:0] coarse_addr; +logic sin_sign, cos_sign; + +logic [8:0] fine_addr; +logic fine_sign; + +always @(posedge clk) begin + coarse_addr <= quadrant[0] ? ~coarse : coarse; + sin_sign <= quadrant[1] ? 1'b1 : 1'b0; + cos_sign <= (quadrant[1] ^ quadrant[0]) ? 1'b1 : 1'b0; + + fine_addr <= fine[9] ? fine[8:0] : ~fine[8:0]; + fine_sign <= fine[9] ? 1'b0 : 1'b1; +end + + +//Pipestage2 +//Sign magnitude values to make full use of Cyclone IV multipliers +logic [18:0] coarse_sin, coarse_cos, coarse_sinp, coarse_cosp; +logic fine_sign_d1, fine_sign_pd1; + +always @(posedge clk) begin + coarse_sinp[18] <= sin_sign; + coarse_cosp[18] <= cos_sign; + fine_sign_pd1 <= fine_sign; +end // always @(posedge clk) + +coarserom #(.init_file("sincos_coarse.txt")) coarserom_i ( + .address(coarse_addr), + .clock(clk), + .q({coarse_sinp[17:0],coarse_cosp[17:0]}) +); + +// Extra pipe to map into optimum RAM and multiplier +always @(posedge clk) begin + coarse_sin <= coarse_sinp; + coarse_cos <= coarse_cosp; + fine_sign_d1 <= fine_sign_pd1; +end + + +//Pipestage2,3 +logic [9:0] scsf, ccsf; +logic [35:0] scsf_ff, ccsf_ff; + +logic unsigned [17:0] sin_opa, sin_opb, cos_opa, cos_opb; +logic unsigned [35:0] sin_mult_res, cos_mult_res; + +generate + if (CALCTYPE == 0) begin: CALCROM + + logic [8:0] fine_sin; + + finerom #(.init_file("sin_fine.txt")) finerom_i ( + .address(fine_addr), + .clock(clk), + .q(fine_sin) + ); + + assign sin_opa = coarse_sinp[17:0]; + assign sin_opb = {9'h00,fine_sin}; + assign scsf_ff = sin_mult_res; + assign cos_opa = coarse_cosp[17:0]; + assign cos_opb = {9'h00,fine_sin}; + assign ccsf_ff = cos_mult_res; + + assign scsf = scsf_ff[26:17]; + assign ccsf = ccsf_ff[26:17]; + + end else if (CALCTYPE == 1) begin: CALCMULT + + logic [17:0] fine_sin; + + // 9x9 unsigned multiply + always @(posedge clk) begin + // 1'b1 is used below as tables are centered around midpoint, + // it will be half after shifting + // 9'h193 is an approximation of 2*pi*64 + fine_sin <= 9'h193 * {fine_addr[8:1],1'b1}; + end + + assign sin_opa = coarse_sinp[17:0]; + assign sin_opb = fine_sin; + assign scsf_ff = sin_mult_res; + assign cos_opa = coarse_cosp[17:0]; + assign cos_opb = fine_sin; + assign ccsf_ff = cos_mult_res; + + // Only 10 bits required for correction factor + assign scsf = scsf_ff[35:26]; + assign ccsf = ccsf_ff[35:26]; + + end else if (CALCTYPE == 2) begin: CALCLOGIC8 + + logic [15:0] fine_sin; + + // 8x8 unsigned multiply in logic + always @(posedge clk) begin + fine_sin <= 8'hca * {fine_addr[8:2],1'b1}; + end + + // Restrict output to 8 bits to reduce LUT usage + assign sin_opa = coarse_sinp[17:0]; + assign sin_opb = {10'h00,fine_sin[15:8]}; + assign scsf_ff = sin_mult_res; + assign cos_opa = coarse_cosp[17:0]; + assign cos_opb = {10'h00,fine_sin[15:8]}; + assign ccsf_ff = cos_mult_res; + + // Only 10 bits required for correction factor + assign scsf = scsf_ff[25:16]; + assign ccsf = ccsf_ff[25:16]; + + end else if (CALCTYPE == 3) begin: CALCLOGIC7 + + logic [13:0] fine_sin; + + always @(posedge clk) begin + // 7x7 + fine_sin <= 7'h65 * {fine_addr[8:3],1'b1}; + end + + // Restrict output to 7 bits to reduce LUT usage + assign sin_opa = coarse_sinp[17:0]; + assign sin_opb = {11'h00,fine_sin[13:7]}; + assign scsf_ff = sin_mult_res; + assign cos_opa = coarse_cosp[17:0]; + assign cos_opb = {11'h00,fine_sin[13:7]}; + assign ccsf_ff = cos_mult_res; + + // Only 10 bits required for correction factor + assign scsf = scsf_ff[24:15]; + assign ccsf = ccsf_ff[24:15]; + + end else if (CALCTYPE == 4) begin: CALCLOGIC7_10 + + logic [16:0] fine_sin; + + always @(posedge clk) begin + // 7x10 + fine_sin <= 7'h65 * {fine_addr[8:0],1'b1}; + end + + // Restrict output to 8 bits to reduce LUT usage + assign sin_opa = coarse_sinp[17:0]; + assign sin_opb = {10'h00,fine_sin[16:9]}; + assign scsf_ff = sin_mult_res; + assign cos_opa = coarse_cosp[17:0]; + assign cos_opb = {10'h00,fine_sin[16:9]}; + assign ccsf_ff = cos_mult_res; + + // Only 10 bits required for correction factor + assign scsf = scsf_ff[25:16]; + assign ccsf = ccsf_ff[25:16]; + + end + +endgenerate + + + +lpm_mult #( .lpm_hint("DEDICATED_MULTIPLIER_CIRCUITRY=YES,MAXIMIZE_SPEED=5"), + .lpm_pipeline(2), + .lpm_representation("UNSIGNED"), + .lpm_type("LPM_MULT"), + .lpm_widtha(18), + .lpm_widthb(18), + .lpm_widthp(36)) + +sinmult ( .clock(clk), + .dataa(sin_opa), + .datab(sin_opb), + .result(sin_mult_res), + .aclr(1'b0), + .clken(1'b1), + .sclr(1'b0), + .sum(1'b0)); + +lpm_mult #( .lpm_hint("DEDICATED_MULTIPLIER_CIRCUITRY=YES,MAXIMIZE_SPEED=5"), + .lpm_pipeline(2), + .lpm_representation("UNSIGNED"), + .lpm_type("LPM_MULT"), + .lpm_widtha(18), + .lpm_widthb(18), + .lpm_widthp(36)) + +cosmult ( .clock(clk), + .dataa(cos_opa), + .datab(cos_opb), + .result(cos_mult_res), + .aclr(1'b0), + .clken(1'b1), + .sclr(1'b0), + .sum(1'b0)); + +// assign sin_mult_res = sin_opa * sin_opb; +// always @(posedge clk) begin +// sin_opa <= coarse_sinp[17:0]; +// sin_opb <= {9'h00,fine_sin}; +// scsf_ff <= sin_mult_res; +// end +// +// assign cos_mult_res = cos_opa * cos_opb; +// always @(posedge clk) begin +// cos_opa <= coarse_cosp[17:0]; +// cos_opb <= {9'h00,fine_sin}; +// ccsf_ff <= cos_mult_res; +// end + + +// Pipestate3 +logic cop, sop; +logic [18:0] sc, cc; +always @(posedge clk) begin + sc <= coarse_sin; + cc <= coarse_cos; +end + +//Compute operation for correction factor +always @(posedge clk) begin + case ({coarse_cos[18],coarse_sin[18],fine_sign_d1}) + 3'b000: cop <= 1'b1; + 3'b001: cop <= 1'b0; + 3'b010: cop <= 1'b0; + 3'b011: cop <= 1'b1; + 3'b100: cop <= 1'b0; + 3'b101: cop <= 1'b1; + 3'b110: cop <= 1'b1; + 3'b111: cop <= 1'b0; + endcase +end + +//Compute operation for correction factor +always @(posedge clk) begin + case ({coarse_sin[18],coarse_cos[18],fine_sign_d1}) + 3'b000: sop <= 1'b0; + 3'b001: sop <= 1'b1; + 3'b010: sop <= 1'b1; + 3'b011: sop <= 1'b0; + 3'b100: sop <= 1'b1; + 3'b101: sop <= 1'b0; + 3'b110: sop <= 1'b0; + 3'b111: sop <= 1'b1; + endcase +end + + +//Pipestage4 +always @(posedge clk) begin + sin[17:0] <= sop ? (sc[17:0] - {1'b0,ccsf}) : (sc[17:0] + {1'b0,ccsf}); + cos[17:0] <= cop ? (cc[17:0] - {1'b0,scsf}) : (cc[17:0] + {1'b0,scsf}); + + sin[18] <= sc[18]; + cos[18] <= cc[18]; +end + +endmodule \ No newline at end of file diff --git a/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/sincos_coarse.txt b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/sincos_coarse.txt new file mode 100644 index 0000000..93fecfe --- /dev/null +++ b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/sincos_coarse.txt @@ -0,0 +1,256 @@ +000000001100100100111111111111111101 // 0 0x324 0x3fffd +000000100101101101111111111111110011 // 1 0x96d 0x3fff3 +000000111110110101111111111111011111 // 2 0xfb5 0x3ffdf +000001010111111101111111111111000010 // 3 0x15fd 0x3ffc2 +000001110001000101111111111110011010 // 4 0x1c45 0x3ff9a +000010001010001101111111111101101001 // 5 0x228d 0x3ff69 +000010100011010100111111111100101110 // 6 0x28d4 0x3ff2e +000010111100011011111111111011101000 // 7 0x2f1b 0x3fee8 +000011010101100010111111111010011010 // 8 0x3562 0x3fe9a +000011101110101000111111111001000001 // 9 0x3ba8 0x3fe41 +000100000111101101111111110111011110 // 10 0x41ed 0x3fdde +000100100000110010111111110101110010 // 11 0x4832 0x3fd72 +000100111001110110111111110011111011 // 12 0x4e76 0x3fcfb +000101010010111010111111110001111011 // 13 0x54ba 0x3fc7b +000101101011111100111111101111110001 // 14 0x5afc 0x3fbf1 +000110000100111110111111101101011101 // 15 0x613e 0x3fb5d +000110011101111111111111101011000000 // 16 0x677f 0x3fac0 +000110110110111110111111101000011000 // 17 0x6dbe 0x3fa18 +000111001111111101111111100101100111 // 18 0x73fd 0x3f967 +000111101000111011111111100010101100 // 19 0x7a3b 0x3f8ac +001000000001110111111111011111100111 // 20 0x8077 0x3f7e7 +001000011010110010111111011100011000 // 21 0x86b2 0x3f718 +001000110011101100111111011001000000 // 22 0x8cec 0x3f640 +001001001100100101111111010101011101 // 23 0x9325 0x3f55d +001001100101011100111111010001110001 // 24 0x995c 0x3f471 +001001111110010001111111001101111100 // 25 0x9f91 0x3f37c +001010010111000101111111001001111100 // 26 0xa5c5 0x3f27c +001010101111111000111111000101110011 // 27 0xabf8 0x3f173 +001011001000101000111111000001100000 // 28 0xb228 0x3f060 +001011100001011000111110111101000011 // 29 0xb858 0x3ef43 +001011111010000101111110111000011101 // 30 0xbe85 0x3ee1d +001100010010110000111110110011101101 // 31 0xc4b0 0x3eced +001100101011011010111110101110110011 // 32 0xcada 0x3ebb3 +001101000100000010111110101001101111 // 33 0xd102 0x3ea6f +001101011100100111111110100100100010 // 34 0xd727 0x3e922 +001101110101001011111110011111001100 // 35 0xdd4b 0x3e7cc +001110001101101100111110011001101011 // 36 0xe36c 0x3e66b +001110100110001011111110010100000001 // 37 0xe98b 0x3e501 +001110111110101000111110001110001101 // 38 0xefa8 0x3e38d +001111010111000011111110001000010000 // 39 0xf5c3 0x3e210 +001111101111011011111110000010001001 // 40 0xfbdb 0x3e089 +010000000111110001111101111011111001 // 41 0x101f1 0x3def9 +010000100000000100111101110101011111 // 42 0x10804 0x3dd5f +010000111000010101111101101110111011 // 43 0x10e15 0x3dbbb +010001010000100011111101101000001110 // 44 0x11423 0x3da0e +010001101000101111111101100001011000 // 45 0x11a2f 0x3d858 +010010000000111000111101011010011000 // 46 0x12038 0x3d698 +010010011000111110111101010011001111 // 47 0x1263e 0x3d4cf +010010110001000001111101001011111100 // 48 0x12c41 0x3d2fc +010011001001000001111101000100011111 // 49 0x13241 0x3d11f +010011100000111111111100111100111001 // 50 0x1383f 0x3cf39 +010011111000111001111100110101001010 // 51 0x13e39 0x3cd4a +010100010000110000111100101101010010 // 52 0x14430 0x3cb52 +010100101000100101111100100101010000 // 53 0x14a25 0x3c950 +010101000000010110111100011101000101 // 54 0x15016 0x3c745 +010101011000000011111100010100110000 // 55 0x15603 0x3c530 +010101101111101110111100001100010010 // 56 0x15bee 0x3c312 +010110000111010101111100000011101011 // 57 0x161d5 0x3c0eb +010110011110111001111011111010111011 // 58 0x167b9 0x3bebb +010110110110011001111011110010000001 // 59 0x16d99 0x3bc81 +010111001101110110111011101000111110 // 60 0x17376 0x3ba3e +010111100101001111111011011111110010 // 61 0x1794f 0x3b7f2 +010111111100100100111011010110011101 // 62 0x17f24 0x3b59d +011000010011110110111011001100111110 // 63 0x184f6 0x3b33e +011000101011000100111011000011010111 // 64 0x18ac4 0x3b0d7 +011001000010001110111010111001100110 // 65 0x1908e 0x3ae66 +011001011001010101111010101111101100 // 66 0x19655 0x3abec +011001110000010111111010100101101010 // 67 0x19c17 0x3a96a +011010000111010110111010011011011110 // 68 0x1a1d6 0x3a6de +011010011110010000111010010001001001 // 69 0x1a790 0x3a449 +011010110101000110111010000110101011 // 70 0x1ad46 0x3a1ab +011011001011111001111001111100000100 // 71 0x1b2f9 0x39f04 +011011100010100111111001110001010101 // 72 0x1b8a7 0x39c55 +011011111001010000111001100110011100 // 73 0x1be50 0x3999c +011100001111110110111001011011011010 // 74 0x1c3f6 0x396da +011100100110010111111001010000010000 // 75 0x1c997 0x39410 +011100111100110100111001000100111101 // 76 0x1cf34 0x3913d +011101010011001100111000111001100001 // 77 0x1d4cc 0x38e61 +011101101001100000111000101101111100 // 78 0x1da60 0x38b7c +011101111111101111111000100010001111 // 79 0x1dfef 0x3888f +011110010101111010111000010110011000 // 80 0x1e57a 0x38598 +011110101011111111111000001010011001 // 81 0x1eaff 0x38299 +011111000010000001110111111110010010 // 82 0x1f081 0x37f92 +011111010111111101110111110010000010 // 83 0x1f5fd 0x37c82 +011111101101110100110111100101101001 // 84 0x1fb74 0x37969 +100000000011100111110111011001000111 // 85 0x200e7 0x37647 +100000011001010101110111001100011110 // 86 0x20655 0x3731e +100000101110111101110110111111101011 // 87 0x20bbd 0x36feb +100001000100100001110110110010110000 // 88 0x21121 0x36cb0 +100001011010000000110110100101101101 // 89 0x21680 0x3696d +100001101111011001110110011000100001 // 90 0x21bd9 0x36621 +100010000100101101110110001011001101 // 91 0x2212d 0x362cd +100010011001111100110101111101110000 // 92 0x2267c 0x35f70 +100010101111000110110101110000001011 // 93 0x22bc6 0x35c0b +100011000100001010110101100010011110 // 94 0x2310a 0x3589e +100011011001001001110101010100101001 // 95 0x23649 0x35529 +100011101110000010110101000110101011 // 96 0x23b82 0x351ab +100100000010110110110100111000100101 // 97 0x240b6 0x34e25 +100100010111100101110100101010010111 // 98 0x245e5 0x34a97 +100100101100001101110100011100000001 // 99 0x24b0d 0x34701 +100101000000110000110100001101100011 // 100 0x25030 0x34363 +100101010101001110110011111110111101 // 101 0x2554e 0x33fbd +100101101001100101110011110000001111 // 102 0x25a65 0x33c0f +100101111101110111110011100001011001 // 103 0x25f77 0x33859 +100110010010000011110011010010011010 // 104 0x26483 0x3349a +100110100110001001110011000011010100 // 105 0x26989 0x330d4 +100110111010001001110010110100000110 // 106 0x26e89 0x32d06 +100111001110000011110010100100110001 // 107 0x27383 0x32931 +100111100001110111110010010101010011 // 108 0x27877 0x32553 +100111110101100101110010000101101110 // 109 0x27d65 0x3216e +101000001001001101110001110110000001 // 110 0x2824d 0x31d81 +101000011100101111110001100110001100 // 111 0x2872f 0x3198c +101000110000001010110001010110001111 // 112 0x28c0a 0x3158f +101001000011011111110001000110001011 // 113 0x290df 0x3118b +101001010110101110110000110110000000 // 114 0x295ae 0x30d80 +101001101001110110110000100101101101 // 115 0x29a76 0x3096d +101001111100111000110000010101010010 // 116 0x29f38 0x30552 +101010001111110100110000000100110000 // 117 0x2a3f4 0x30130 +101010100010101001101111110100000110 // 118 0x2a8a9 0x2fd06 +101010110101010111101111100011010110 // 119 0x2ad57 0x2f8d6 +101011000111111111101111010010011101 // 120 0x2b1ff 0x2f49d +101011011010100000101111000001011110 // 121 0x2b6a0 0x2f05e +101011101100111010101110110000010111 // 122 0x2bb3a 0x2ec17 +101011111111001110101110011111001001 // 123 0x2bfce 0x2e7c9 +101100010001011011101110001101110100 // 124 0x2c45b 0x2e374 +101100100011100001101101111100011000 // 125 0x2c8e1 0x2df18 +101100110101100001101101101010110101 // 126 0x2cd61 0x2dab5 +101101000111011001101101011001001010 // 127 0x2d1d9 0x2d64a +101101011001001010101101000111011001 // 128 0x2d64a 0x2d1d9 +101101101010110101101100110101100001 // 129 0x2dab5 0x2cd61 +101101111100011000101100100011100001 // 130 0x2df18 0x2c8e1 +101110001101110100101100010001011011 // 131 0x2e374 0x2c45b +101110011111001001101011111111001110 // 132 0x2e7c9 0x2bfce +101110110000010111101011101100111010 // 133 0x2ec17 0x2bb3a +101111000001011110101011011010100000 // 134 0x2f05e 0x2b6a0 +101111010010011101101011000111111111 // 135 0x2f49d 0x2b1ff +101111100011010110101010110101010111 // 136 0x2f8d6 0x2ad57 +101111110100000110101010100010101001 // 137 0x2fd06 0x2a8a9 +110000000100110000101010001111110100 // 138 0x30130 0x2a3f4 +110000010101010010101001111100111000 // 139 0x30552 0x29f38 +110000100101101101101001101001110110 // 140 0x3096d 0x29a76 +110000110110000000101001010110101110 // 141 0x30d80 0x295ae +110001000110001011101001000011011111 // 142 0x3118b 0x290df +110001010110001111101000110000001010 // 143 0x3158f 0x28c0a +110001100110001100101000011100101111 // 144 0x3198c 0x2872f +110001110110000001101000001001001101 // 145 0x31d81 0x2824d +110010000101101110100111110101100101 // 146 0x3216e 0x27d65 +110010010101010011100111100001110111 // 147 0x32553 0x27877 +110010100100110001100111001110000011 // 148 0x32931 0x27383 +110010110100000110100110111010001001 // 149 0x32d06 0x26e89 +110011000011010100100110100110001001 // 150 0x330d4 0x26989 +110011010010011010100110010010000011 // 151 0x3349a 0x26483 +110011100001011001100101111101110111 // 152 0x33859 0x25f77 +110011110000001111100101101001100101 // 153 0x33c0f 0x25a65 +110011111110111101100101010101001110 // 154 0x33fbd 0x2554e +110100001101100011100101000000110000 // 155 0x34363 0x25030 +110100011100000001100100101100001101 // 156 0x34701 0x24b0d +110100101010010111100100010111100101 // 157 0x34a97 0x245e5 +110100111000100101100100000010110110 // 158 0x34e25 0x240b6 +110101000110101011100011101110000010 // 159 0x351ab 0x23b82 +110101010100101001100011011001001001 // 160 0x35529 0x23649 +110101100010011110100011000100001010 // 161 0x3589e 0x2310a +110101110000001011100010101111000110 // 162 0x35c0b 0x22bc6 +110101111101110000100010011001111100 // 163 0x35f70 0x2267c +110110001011001101100010000100101101 // 164 0x362cd 0x2212d +110110011000100001100001101111011001 // 165 0x36621 0x21bd9 +110110100101101101100001011010000000 // 166 0x3696d 0x21680 +110110110010110000100001000100100001 // 167 0x36cb0 0x21121 +110110111111101011100000101110111101 // 168 0x36feb 0x20bbd +110111001100011110100000011001010101 // 169 0x3731e 0x20655 +110111011001000111100000000011100111 // 170 0x37647 0x200e7 +110111100101101001011111101101110100 // 171 0x37969 0x1fb74 +110111110010000010011111010111111101 // 172 0x37c82 0x1f5fd +110111111110010010011111000010000001 // 173 0x37f92 0x1f081 +111000001010011001011110101011111111 // 174 0x38299 0x1eaff +111000010110011000011110010101111010 // 175 0x38598 0x1e57a +111000100010001111011101111111101111 // 176 0x3888f 0x1dfef +111000101101111100011101101001100000 // 177 0x38b7c 0x1da60 +111000111001100001011101010011001100 // 178 0x38e61 0x1d4cc +111001000100111101011100111100110100 // 179 0x3913d 0x1cf34 +111001010000010000011100100110010111 // 180 0x39410 0x1c997 +111001011011011010011100001111110110 // 181 0x396da 0x1c3f6 +111001100110011100011011111001010000 // 182 0x3999c 0x1be50 +111001110001010101011011100010100111 // 183 0x39c55 0x1b8a7 +111001111100000100011011001011111001 // 184 0x39f04 0x1b2f9 +111010000110101011011010110101000110 // 185 0x3a1ab 0x1ad46 +111010010001001001011010011110010000 // 186 0x3a449 0x1a790 +111010011011011110011010000111010110 // 187 0x3a6de 0x1a1d6 +111010100101101010011001110000010111 // 188 0x3a96a 0x19c17 +111010101111101100011001011001010101 // 189 0x3abec 0x19655 +111010111001100110011001000010001110 // 190 0x3ae66 0x1908e +111011000011010111011000101011000100 // 191 0x3b0d7 0x18ac4 +111011001100111110011000010011110110 // 192 0x3b33e 0x184f6 +111011010110011101010111111100100100 // 193 0x3b59d 0x17f24 +111011011111110010010111100101001111 // 194 0x3b7f2 0x1794f +111011101000111110010111001101110110 // 195 0x3ba3e 0x17376 +111011110010000001010110110110011001 // 196 0x3bc81 0x16d99 +111011111010111011010110011110111001 // 197 0x3bebb 0x167b9 +111100000011101011010110000111010101 // 198 0x3c0eb 0x161d5 +111100001100010010010101101111101110 // 199 0x3c312 0x15bee +111100010100110000010101011000000011 // 200 0x3c530 0x15603 +111100011101000101010101000000010110 // 201 0x3c745 0x15016 +111100100101010000010100101000100101 // 202 0x3c950 0x14a25 +111100101101010010010100010000110000 // 203 0x3cb52 0x14430 +111100110101001010010011111000111001 // 204 0x3cd4a 0x13e39 +111100111100111001010011100000111111 // 205 0x3cf39 0x1383f +111101000100011111010011001001000001 // 206 0x3d11f 0x13241 +111101001011111100010010110001000001 // 207 0x3d2fc 0x12c41 +111101010011001111010010011000111110 // 208 0x3d4cf 0x1263e +111101011010011000010010000000111000 // 209 0x3d698 0x12038 +111101100001011000010001101000101111 // 210 0x3d858 0x11a2f +111101101000001110010001010000100011 // 211 0x3da0e 0x11423 +111101101110111011010000111000010101 // 212 0x3dbbb 0x10e15 +111101110101011111010000100000000100 // 213 0x3dd5f 0x10804 +111101111011111001010000000111110001 // 214 0x3def9 0x101f1 +111110000010001001001111101111011011 // 215 0x3e089 0xfbdb +111110001000010000001111010111000011 // 216 0x3e210 0xf5c3 +111110001110001101001110111110101000 // 217 0x3e38d 0xefa8 +111110010100000001001110100110001011 // 218 0x3e501 0xe98b +111110011001101011001110001101101100 // 219 0x3e66b 0xe36c +111110011111001100001101110101001011 // 220 0x3e7cc 0xdd4b +111110100100100010001101011100100111 // 221 0x3e922 0xd727 +111110101001101111001101000100000010 // 222 0x3ea6f 0xd102 +111110101110110011001100101011011010 // 223 0x3ebb3 0xcada +111110110011101101001100010010110000 // 224 0x3eced 0xc4b0 +111110111000011101001011111010000101 // 225 0x3ee1d 0xbe85 +111110111101000011001011100001011000 // 226 0x3ef43 0xb858 +111111000001100000001011001000101000 // 227 0x3f060 0xb228 +111111000101110011001010101111111000 // 228 0x3f173 0xabf8 +111111001001111100001010010111000101 // 229 0x3f27c 0xa5c5 +111111001101111100001001111110010001 // 230 0x3f37c 0x9f91 +111111010001110001001001100101011100 // 231 0x3f471 0x995c +111111010101011101001001001100100101 // 232 0x3f55d 0x9325 +111111011001000000001000110011101100 // 233 0x3f640 0x8cec +111111011100011000001000011010110010 // 234 0x3f718 0x86b2 +111111011111100111001000000001110111 // 235 0x3f7e7 0x8077 +111111100010101100000111101000111011 // 236 0x3f8ac 0x7a3b +111111100101100111000111001111111101 // 237 0x3f967 0x73fd +111111101000011000000110110110111110 // 238 0x3fa18 0x6dbe +111111101011000000000110011101111111 // 239 0x3fac0 0x677f +111111101101011101000110000100111110 // 240 0x3fb5d 0x613e +111111101111110001000101101011111100 // 241 0x3fbf1 0x5afc +111111110001111011000101010010111010 // 242 0x3fc7b 0x54ba +111111110011111011000100111001110110 // 243 0x3fcfb 0x4e76 +111111110101110010000100100000110010 // 244 0x3fd72 0x4832 +111111110111011110000100000111101101 // 245 0x3fdde 0x41ed +111111111001000001000011101110101000 // 246 0x3fe41 0x3ba8 +111111111010011010000011010101100010 // 247 0x3fe9a 0x3562 +111111111011101000000010111100011011 // 248 0x3fee8 0x2f1b +111111111100101110000010100011010100 // 249 0x3ff2e 0x28d4 +111111111101101001000010001010001101 // 250 0x3ff69 0x228d +111111111110011010000001110001000101 // 251 0x3ff9a 0x1c45 +111111111111000010000001010111111101 // 252 0x3ffc2 0x15fd +111111111111011111000000111110110101 // 253 0x3ffdf 0xfb5 +111111111111110011000000100101101101 // 254 0x3fff3 0x96d +111111111111111101000000001100100100 // 255 0x3fffd 0x324 diff --git a/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/tables.py b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/tables.py new file mode 100644 index 0000000..85e8fc6 --- /dev/null +++ b/WSPRBerry/wsprberry-verilog-fpga/rtl/nco/tables.py @@ -0,0 +1,47 @@ + +import numpy as np +from scipy import signal + + +def sincos_coarse(coarsebits=10,resbits=18,maxoff=2): + + f = open("sincos_coarse.txt","w") + + for sv in range(2**(coarsebits-2)): + x = (sv+0.5)/(2**coarsebits) + + sinx = np.sin(2*np.pi * x) + sinx = int(np.round(sinx*(2**resbits-maxoff))) + + cosx = np.cos(2*np.pi * x) + cosx = int(np.round(cosx*(2**resbits-maxoff))) + + #print(sv,hex(sinx),hex(cosx)) + f.write("{0:018b}{1:018b} // {2} {3} {4}\n".format(sinx,cosx,sv,hex(sinx),hex(cosx))) + + f.close() + +def sin_fine(coarsebits=10,finebits=10,resbits=18,maxoff=2): + + f = open("sin_fine.txt","w") + + for sv in range(2**(finebits-1)): + + x = (sv+0.5)/(2**(coarsebits+finebits)) + + finesinx = np.sin(2*np.pi * x) + finesinxf = int(np.round(finesinx*(2**resbits-maxoff))) + finesinxt = int(np.round(finesinx*(2**(resbits-1)-maxoff))) + + f.write("{0:09b} // {1} {2}\n".format(finesinxt,sv,hex(finesinxf))) + #print(sv,hex(finesinxt)) + + f.close() + + +sincos_coarse() + +sin_fine() + + + diff --git a/WSPRBerry/wsprberry-verilog-fpga/rtl/radio_openhpsdr/receiver_nco.v b/WSPRBerry/wsprberry-verilog-fpga/rtl/radio_openhpsdr/receiver_nco.v new file mode 100644 index 0000000..098c2da --- /dev/null +++ b/WSPRBerry/wsprberry-verilog-fpga/rtl/radio_openhpsdr/receiver_nco.v @@ -0,0 +1,135 @@ +/* +-------------------------------------------------------------------------------- +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the +Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +Boston, MA 02110-1301, USA. +-------------------------------------------------------------------------------- +*/ + + +//------------------------------------------------------------------------------ +// Copyright (c) 2008 Alex Shovkoplyas, VE3NEA +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Copyright (c) 2013 Phil Harman, VK6APH +//------------------------------------------------------------------------------ + +// 2013 Jan 26 - varcic now accepts 2...40 as decimation and CFIR +// replaced with Polyphase FIR - VK6APH + +// 2015 Jan 31 - updated for Hermes-Lite 12bit Steve Haynal KF7O + +module receiver_nco( + input clock, //61.44 MHz + input clock_2x, + input [5:0] rate, //48k....384k + input signed [17:0] mixdata_I, + input signed [17:0] mixdata_Q, + output out_strobe, + output [23:0] out_data_I, + output [23:0] out_data_Q + ); + + parameter CICRATE; + +// gain adjustment, Hermes reduced by 6dB to match previous receiver code. +// Hermes-Lite gain reduced to calibrate QtRadio +wire signed [23:0] out_data_I2; +wire signed [23:0] out_data_Q2; +assign out_data_I = out_data_I2; //>>> 3); +assign out_data_Q = out_data_Q2; //>>> 3); + + +// Receive CIC filters followed by FIR filter +wire decimA_avail, decimB_avail; +wire signed [15:0] decimA_real, decimA_imag; +wire signed [15:0] decimB_real, decimB_imag; +wire signed [15:0] decimC_real, decimC_imag; + +localparam VARCICWIDTH = (CICRATE == 10) ? 36 : (CICRATE == 13) ? 36 : (CICRATE == 5) ? 43 : 39; // Last is default rate of 8 +localparam ACCWIDTH = (CICRATE == 10) ? 28 : (CICRATE == 13) ? 30 : (CICRATE == 5) ? 25 : 27; // Last is default rate of 8 + + +// CIC filter +//I channel +cic #(.STAGES(3), .DECIMATION(CICRATE), .IN_WIDTH(18), .ACC_WIDTH(ACCWIDTH), .OUT_WIDTH(16)) + cic_inst_I2( + .clock(clock), + .in_strobe(1'b1), + .out_strobe(decimA_avail), + .in_data(mixdata_I), + .out_data(decimA_real) + ); + +//Q channel +cic #(.STAGES(3), .DECIMATION(CICRATE), .IN_WIDTH(18), .ACC_WIDTH(ACCWIDTH), .OUT_WIDTH(16)) + cic_inst_Q2( + .clock(clock), + .in_strobe(1'b1), + .out_strobe(), + .in_data(mixdata_Q), + .out_data(decimA_imag) + ); + + +// Variable CIC filter - in width = out width = 14 bits, decimation rate = 2 to 16 +//I channel +varcic #(.STAGES(5), .IN_WIDTH(16), .ACC_WIDTH(VARCICWIDTH), .OUT_WIDTH(16), .CICRATE(CICRATE)) + varcic_inst_I1( + .clock(clock), + .in_strobe(decimA_avail), + .decimation(6'd40), + .out_strobe(decimB_avail), + .in_data(decimA_real), + .out_data(decimB_real) + ); + +//Q channel +varcic #(.STAGES(5), .IN_WIDTH(16), .ACC_WIDTH(VARCICWIDTH), .OUT_WIDTH(16), .CICRATE(CICRATE)) + varcic_inst_Q1( + .clock(clock), + .in_strobe(decimA_avail), + .decimation(6'd40), + .out_strobe(), + .in_data(decimA_imag), + .out_data(decimB_imag) + ); + + + +// Variable CIC filter - in width = out width = 14 bits, decimation rate = 2 to 16 +//I channel +varcic #(.STAGES(5), .IN_WIDTH(16), .ACC_WIDTH(VARCICWIDTH), .OUT_WIDTH(16), .CICRATE(CICRATE)) + varcic_inst2_I1( + .clock(clock), + .in_strobe(decimB_avail), + .decimation(6'd40), + .out_strobe(decimC_avail), + .in_data(decimB_real), + .out_data(decimC_real) + ); + +//Q channel +varcic #(.STAGES(5), .IN_WIDTH(16), .ACC_WIDTH(VARCICWIDTH), .OUT_WIDTH(16), .CICRATE(CICRATE)) + varcic_inst2_Q1( + .clock(clock), + .in_strobe(decimB_avail), + .decimation(6'd40), + .out_strobe(), + .in_data(decimB_imag), + .out_data(decimC_imag) + ); + +firX8R8 fir2 (clock, clock_2x, decimC_avail, {{2{decimC_real[15]}},decimC_real}, {{2{decimC_imag[15]}},decimC_imag}, out_strobe, out_data_I2, out_data_Q2); + +endmodule diff --git a/fd-firmware/verilog-fpga/rtl/radioberry.v b/fd-firmware/verilog-fpga/rtl/radioberry.v index 0d19e8a..30c73de 100644 --- a/fd-firmware/verilog-fpga/rtl/radioberry.v +++ b/fd-firmware/verilog-fpga/rtl/radioberry.v @@ -30,7 +30,7 @@ clk_76m8, ad9866_clk,ad9866_rx,ad9866_tx,ad9866_rxsync,ad9866_rxclk,ad9866_txsync,ad9866_txquietn,ad9866_sclk,ad9866_sdio,ad9866_sdo,ad9866_sen_n,ad9866_rst_n,ad9866_mode, spi_sck, spi_mosi, spi_miso, spi_ce, pi_clk, pi_clk2, rx_samples, data, -ptt_in, EER_PWM_out); +ptt_in, ptt_out, EER_PWM_out); input wire clk_76m8; input wire ad9866_clk; @@ -64,6 +64,7 @@ output wire rx_samples; output [7:0] data; input wire ptt_in; +output wire ptt_out; reg [9:0] PWM_min; // sets minimum width of envelope PWM pulse reg [9:0] PWM_max; // sets maximum width of envelope PWM pulse @@ -78,6 +79,7 @@ logic clk_ad9866_2x; assign ad9866_mode = 1'b1; //FULLDUPLEX assign ad9866_rst_n = ~reset; +assign ptt_out = ptt_in; // RX Path logic [11:0] rx_data_assemble; diff --git a/fd-firmware/verilog-fpga/tcl/locations_radioberry_fd.tcl b/fd-firmware/verilog-fpga/tcl/locations_radioberry_fd.tcl index ea0c844..6031869 100644 --- a/fd-firmware/verilog-fpga/tcl/locations_radioberry_fd.tcl +++ b/fd-firmware/verilog-fpga/tcl/locations_radioberry_fd.tcl @@ -2,6 +2,7 @@ set_location_assignment PIN_53 -to clk_76m8 set_location_assignment PIN_42 -to ptt_in set_location_assignment PIN_115 -to EER_PWM_out +set_location_assignment PIN_144 -to ptt_out set_location_assignment PIN_50 -to spi_ce[1] set_location_assignment PIN_51 -to spi_ce[0] diff --git a/hardware/release/beta3/bom/.~lock.2019-02-03T131242.xlsx# b/hardware/release/beta3/bom/.~lock.2019-02-03T131242.xlsx# new file mode 100644 index 0000000..2e53cb3 --- /dev/null +++ b/hardware/release/beta3/bom/.~lock.2019-02-03T131242.xlsx# @@ -0,0 +1 @@ +,LAPTOP-E9KMQT1S/pa3gsb,LAPTOP-E9KMQT1S,03.02.2019 20:16,file:///C:/Users/pa3gsb/AppData/Roaming/OpenOffice/4; \ No newline at end of file diff --git a/hardware/release/beta3/bom/2019-02-03T131242.xlsx b/hardware/release/beta3/bom/2019-02-03T131242.xlsx new file mode 100644 index 0000000..b694931 Binary files /dev/null and b/hardware/release/beta3/bom/2019-02-03T131242.xlsx differ diff --git a/software/hermes-emulator/hermeslite.c b/software/hermes-emulator/hermeslite.c index f831502..e394fc0 100644 --- a/software/hermes-emulator/hermeslite.c +++ b/software/hermes-emulator/hermeslite.c @@ -47,6 +47,7 @@ #include #include #include +#define __USE_GNU #include @@ -158,6 +159,7 @@ int alex_manual = 0; uint16_t i2c_alex_data = 0; uint16_t i2c_data = 0; + float timedifference_msec(struct timeval t0, struct timeval t1) { return (t1.tv_sec - t0.tv_sec) * 1000.0f + (t1.tv_usec - t0.tv_usec) / 1000.0f; @@ -240,10 +242,34 @@ int main(int argc, char **argv) printf("init done \n"); - pthread_t pid1, pid2, pid3; - pthread_create(&pid1, NULL, packetreader, NULL); - pthread_create(&pid2, NULL, spiWriter, NULL); - pthread_create(&pid3, NULL, spiReader, NULL); + pthread_t pid1, pid2, pid3, pid4; + pthread_create(&pid2, NULL, packetreader, NULL); + pthread_create(&pid3, NULL, spiWriter, NULL); + pthread_create(&pid4, NULL, spiReader, NULL); + + + // cpu_set_t: This data set is a bitset where each bit represents a CPU. + cpu_set_t cpuset0; + cpu_set_t cpuset1; + cpu_set_t cpuset2; + cpu_set_t cpuset3; + // CPU_ZERO: This macro initializes the CPU set set to be the empty set. + CPU_ZERO(&cpuset0); + CPU_ZERO(&cpuset1); + CPU_ZERO(&cpuset2); + CPU_ZERO(&cpuset3); + // CPU_SET: This macro adds cpu to the CPU set set. + CPU_SET(0, &cpuset0); + CPU_SET(1, &cpuset1); + CPU_SET(2, &cpuset2); + CPU_SET(3, &cpuset3); + + //pthread_setaffinity_np + //sched_setaffinity(pid2, sizeof(cpu_set_t), &cpuset0); + pthread_setaffinity_np(pid2, sizeof(cpu_set_t), &cpuset0); + + //sched_setaffinity(pid4, sizeof(cpu_set_t), &cpuset1); + pthread_setaffinity_np(pid4, sizeof(cpu_set_t), &cpuset1); /* create a UDP socket */ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {