mirror of
https://github.com/UzixLS/zx-multisound.git
synced 2025-07-18 23:01:31 +03:00
add testbench
This commit is contained in:
31
cpld/tb/Makefile
Normal file
31
cpld/tb/Makefile
Normal file
@ -0,0 +1,31 @@
|
||||
export PATH:=/opt/modelsim201/modelsim_ase/bin:/cygdrive/c/Hwdev/modelsim181/modelsim_ase/win32aloem:/cygdrive/c/Hwdev/iverilog/bin/:/cygdrive/c/Hwdev/sjasmplus/:/cygdrive/c/Dev/srec/:${PATH}
|
||||
|
||||
all: testbench_top
|
||||
|
||||
testbench_top: IVFLAGS+=-I../rtl/
|
||||
testbench_top: VSIMFLAGS+=+nowarn3722 +nowarn8822 +nowarn3017 +nowarn3155
|
||||
testbench_top: testbench_top.v sine_dds.v
|
||||
|
||||
xtestbench_%:
|
||||
iverilog -g2005-sv ${IVFLAGS} -o $@.vvp $^
|
||||
vvp $@.vvp
|
||||
@rm $@.vvp
|
||||
|
||||
testbench_%:
|
||||
test ! -d work || rm -rf work
|
||||
vlib work
|
||||
test ! -n "$(filter %.v %.sv,$^)" || vlog -quiet -sv ${VLOGFLAGS} $(filter %.v %sv,$^)
|
||||
test ! -n "$(filter %.vhd %.vhdl,$^)" || vcom -quiet ${VCOMFLAGS} $(filter %.vhd %.vhdl,$^)
|
||||
vsim ${VSIMFLAGS} -batch -quiet -do 'run -all' $@
|
||||
test ! -r transcript || rm transcript
|
||||
|
||||
%.bin: %.asm
|
||||
sjasmplus $<
|
||||
|
||||
%.mem: %.bin
|
||||
srec_cat $< -binary -o $@ -vmem 8
|
||||
|
||||
clean:
|
||||
rm -rf ivl_vhdl_work/ work/ *.bin *.mem *.vcd
|
||||
|
||||
-include Makefile.local
|
40
cpld/tb/circuit.asc
Normal file
40
cpld/tb/circuit.asc
Normal file
@ -0,0 +1,40 @@
|
||||
Version 4
|
||||
SHEET 1 880 680
|
||||
WIRE 48 176 48 160
|
||||
WIRE 96 176 48 176
|
||||
WIRE 224 176 224 160
|
||||
WIRE 224 176 176 176
|
||||
WIRE 288 176 224 176
|
||||
WIRE 432 176 432 160
|
||||
WIRE 432 176 352 176
|
||||
WIRE 224 192 224 176
|
||||
FLAG 48 256 0
|
||||
FLAG 224 256 0
|
||||
FLAG 432 256 0
|
||||
FLAG 432 160 Out
|
||||
FLAG 48 160 In
|
||||
FLAG 224 160 Mid
|
||||
SYMBOL res 80 192 R270
|
||||
WINDOW 0 32 56 VTop 2
|
||||
WINDOW 3 0 56 VBottom 2
|
||||
SYMATTR InstName R6
|
||||
SYMATTR Value 1k
|
||||
SYMBOL voltage 48 160 R0
|
||||
WINDOW 0 -45 35 Bottom 2
|
||||
WINDOW 3 -95 81 Top 2
|
||||
WINDOW 123 0 0 Left 0
|
||||
WINDOW 39 0 0 Left 0
|
||||
SYMATTR InstName V5
|
||||
SYMATTR Value PWL file=testbench_pwl.txt
|
||||
SYMBOL cap 208 192 R0
|
||||
SYMATTR InstName C1
|
||||
SYMATTR Value 10n
|
||||
SYMBOL res 416 160 R0
|
||||
SYMATTR InstName R1
|
||||
SYMATTR Value 100k
|
||||
SYMBOL cap 352 160 R90
|
||||
WINDOW 0 0 32 VBottom 2
|
||||
WINDOW 3 32 32 VTop 2
|
||||
SYMATTR InstName C2
|
||||
SYMATTR Value 1n
|
||||
TEXT -24 112 Left 2 !.tran 10m
|
1
cpld/tb/sine.mem
Normal file
1
cpld/tb/sine.mem
Normal file
@ -0,0 +1 @@
|
||||
@00000000 8000 80c9 8192 825b 8324 83ee 84b7 8580 8649 8712 87db 88a4 896c 8a35 8afe 8bc6 8c8e 8d57 8e1f 8ee7 8fae 9076 913e 9205 92cc 9393 945a 9521 95e7 96ad 9773 9839 98fe 99c4 9a89 9b4d 9c12 9cd6 9d9a 9e5e 9f21 9fe4 a0a7 a169 a22b a2ed a3af a470 a530 a5f1 a6b1 a770 a830 a8ef a9ad aa6b ab29 abe6 aca3 ad5f ae1b aed7 af92 b04d b107 b1c0 b27a b332 b3ea b4a2 b559 b610 b6c6 b77c b831 b8e5 b999 ba4d bb00 bbb2 bc64 bd15 bdc6 be76 bf25 bfd4 c082 c12f c1dc c288 c334 c3df c489 c533 c5dc c684 c72c c7d3 c879 c91f c9c3 ca67 cb0b cbae cc4f ccf1 cd91 ce31 ced0 cf6e d00b d0a8 d144 d1df d279 d313 d3ac d443 d4db d571 d606 d69b d72f d7c2 d854 d8e5 d975 da05 da93 db21 dbae dc3a dcc5 dd4f ddd9 de61 dee9 df6f dff5 e07a e0fd e180 e202 e283 e303 e382 e400 e47d e4fa e575 e5ef e668 e6e0 e758 e7ce e843 e8b7 e92b e99d ea0e ea7e eaed eb5b ebc8 ec34 ec9f ed09 ed72 edda ee41 eea7 ef0b ef6f efd1 f033 f093 f0f2 f150 f1ad f209 f264 f2be f316 f36e f3c4 f41a f46e f4c1 f513 f564 f5b3 f602 f64f f69b f6e6 f730 f779 f7c1 f807 f84d f891 f8d4 f916 f956 f996 f9d4 fa11 fa4d fa88 fac1 fafa fb31 fb67 fb9c fbd0 fc02 fc33 fc63 fc92 fcc0 fcec fd17 fd42 fd6a fd92 fdb8 fdde fe01 fe24 fe46 fe66 fe85 fea3 fec0 fedb fef5 ff0e ff26 ff3c ff52 ff66 ff79 ff8a ff9b ffaa ffb8 ffc4 ffd0 ffda ffe3 ffeb fff1 fff6 fffa fffd ffff ffff fffe fffc fff8 fff4 ffee ffe7 ffdf ffd5 ffca ffbe ffb1 ffa2 ff93 ff82 ff6f ff5c ff47 ff31 ff1a ff02 fee8 fece feb1 fe94 fe76 fe56 fe35 fe13 fdf0 fdcb fda5 fd7e fd56 fd2d fd02 fcd6 fca9 fc7b fc4b fc1b fbe9 fbb6 fb82 fb4c fb16 fade faa5 fa6b fa2f f9f3 f9b5 f976 f936 f8f5 f8b2 f86f f82a f7e4 f79d f755 f70c f6c1 f675 f629 f5db f58c f53b f4ea f498 f444 f3ef f399 f342 f2ea f291 f237 f1db f17f f121 f0c3 f063 f002 efa0 ef3d eed9 ee74 ee0e eda6 ed3e ecd5 ec6a ebff eb92 eb24 eab6 ea46 e9d6 e964 e8f1 e87d e809 e793 e71c e6a4 e62c e5b2 e537 e4bc e43f e3c1 e343 e2c3 e243 e1c1 e13f e0bc e037 dfb2 df2c dea5 de1d dd94 dd0a dc80 dbf4 db68 dada da4c d9bd d92d d89c d80b d778 d6e5 d651 d5bc d526 d48f d3f8 d35f d2c6 d22c d192 d0f6 d05a cfbd cf1f ce80 cde1 cd41 cca0 cbff cb5c cab9 ca16 c971 c8cc c826 c77f c6d8 c630 c588 c4de c434 c38a c2de c232 c186 c0d9 c02b bf7c becd be1e bd6d bcbd bc0b bb59 baa6 b9f3 b940 b88b b7d6 b721 b66b b5b5 b4fe b446 b38e b2d6 b21d b164 b0aa afef af34 ae79 adbd ad01 ac45 ab88 aaca aa0c a94e a88f a7d0 a711 a651 a591 a4d0 a40f a34e a28c a1ca a108 a045 9f83 9ebf 9dfc 9d38 9c74 9bb0 9aeb 9a26 9961 989c 97d6 9710 964a 9584 94bd 93f7 9330 9269 91a1 90da 9012 8f4b 8e83 8dbb 8cf3 8c2a 8b62 8a99 89d1 8908 883f 8776 86ad 85e4 851b 8452 8389 82c0 81f7 812d 8064 7f9b 7ed2 7e08 7d3f 7c76 7bad 7ae4 7a1b 7952 7889 77c0 76f7 762e 7566 749d 73d5 730c 7244 717c 70b4 6fed 6f25 6e5e 6d96 6ccf 6c08 6b42 6a7b 69b5 68ef 6829 6763 669e 65d9 6514 644f 638b 62c7 6203 6140 607c 5fba 5ef7 5e35 5d73 5cb1 5bf0 5b2f 5a6e 59ae 58ee 582f 5770 56b1 55f3 5535 5477 53ba 52fe 5242 5186 50cb 5010 4f55 4e9b 4de2 4d29 4c71 4bb9 4b01 4a4a 4994 48de 4829 4774 46bf 460c 4559 44a6 43f4 4342 4292 41e1 4132 4083 3fd4 3f26 3e79 3dcd 3d21 3c75 3bcb 3b21 3a77 39cf 3927 3880 37d9 3733 368e 35e9 3546 34a3 3400 335f 32be 321e 317f 30e0 3042 2fa5 2f09 2e6d 2dd3 2d39 2ca0 2c07 2b70 2ad9 2a43 29ae 291a 2887 27f4 2763 26d2 2642 25b3 2525 2497 240b 237f 22f5 226b 21e2 215a 20d3 204d 1fc8 1f43 1ec0 1e3e 1dbc 1d3c 1cbc 1c3e 1bc0 1b43 1ac8 1a4d 19d3 195b 18e3 186c 17f6 1782 170e 169b 1629 15b9 1549 14db 146d 1400 1395 132a 12c1 1259 11f1 118b 1126 10c2 105f ffd f9c f3c ede e80 e24 dc8 d6e d15 cbd c66 c10 bbb b67 b15 ac4 a73 a24 9d6 98a 93e 8f3 8aa 862 81b 7d5 790 74d 70a 6c9 689 64a 60c 5d0 594 55a 521 4e9 4b3 47d 449 416 3e4 3b4 384 356 329 2fd 2d2 2a9 281 25a 234 20f 1ec 1ca 1a9 189 16b 14e 131 117 fd e5 ce b8 a3 90 7d 6c 5d 4e 41 35 2a 20 18 11 b 7 3 1 0 0 2 5 9 e 14 1c 25 2f 3b 47 55 64 75 86 99 ad c3 d9 f1 10a 124 13f 15c 17a 199 1b9 1db 1fe 221 247 26d 295 2bd 2e8 313 33f 36d 39c 3cc 3fd 42f 463 498 4ce 505 53e 577 5b2 5ee 62b 669 6a9 6e9 72b 76e 7b2 7f8 83e 886 8cf 919 964 9b0 9fd a4c a9b aec b3e b91 be5 c3b c91 ce9 d41 d9b df6 e52 eaf f0d f6c fcc 102e 1090 10f4 1158 11be 1225 128d 12f6 1360 13cb 1437 14a4 1512 1581 15f1 1662 16d4 1748 17bc 1831 18a7 191f 1997 1a10 1a8a 1b05 1b82 1bff 1c7d 1cfc 1d7c 1dfd 1e7f 1f02 1f85 200a 2090 2116 219e 2226 22b0 233a 23c5 2451 24de 256c 25fa 268a 271a 27ab 283d 28d0 2964 29f9 2a8e 2b24 2bbc 2c53 2cec 2d86 2e20 2ebb 2f57 2ff4 3091 312f 31ce 326e 330e 33b0 3451 34f4 3598 363c 36e0 3786 382c 38d3 397b 3a23 3acc 3b76 3c20 3ccb 3d77 3e23 3ed0 3f7d 402b 40da 4189 4239 42ea 439b 444d 44ff 45b2 4666 471a 47ce 4883 4939 49ef 4aa6 4b5d 4c15 4ccd 4d85 4e3f 4ef8 4fb2 506d 5128 51e4 52a0 535c 5419 54d6 5594 5652 5710 57cf 588f 594e 5a0e 5acf 5b8f 5c50 5d12 5dd4 5e96 5f58 601b 60de 61a1 6265 6329 63ed 64b2 6576 663b 6701 67c6 688c 6952 6a18 6ade 6ba5 6c6c 6d33 6dfa 6ec1 6f89 7051 7118 71e0 72a8 7371 7439 7501 75ca 7693 775b 7824 78ed 79b6 7a7f 7b48 7c11 7cdb 7da4 7e6d 7f36 8000
|
43
cpld/tb/sine_dds.v
Normal file
43
cpld/tb/sine_dds.v
Normal file
@ -0,0 +1,43 @@
|
||||
module sine_dds(
|
||||
input clk ,
|
||||
input reset,
|
||||
input [23:0] fcw,
|
||||
output [15:0] dds_sin,
|
||||
output dds_clk,
|
||||
output dds_stb
|
||||
);
|
||||
reg [15:0] rom_memory [1023:0];
|
||||
initial begin
|
||||
$readmemh("sine.mem", rom_memory);
|
||||
end
|
||||
reg [23:0] accu;
|
||||
reg [1:0] fdiv_cnt;
|
||||
wire accu_en;
|
||||
reg accu_msb_q;
|
||||
wire [9:0] lut_index;
|
||||
|
||||
//process for frequency divider
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(reset == 1'b1)
|
||||
fdiv_cnt <= 0; //synchronous reset
|
||||
else if(accu_en == 1'b1)
|
||||
fdiv_cnt <= 0;
|
||||
else
|
||||
fdiv_cnt <= fdiv_cnt +1;
|
||||
end
|
||||
//logic for accu enable signal, resets also the frequency divider counter
|
||||
assign accu_en = (fdiv_cnt == 2'd2) ? 1'b1 : 1'b0;
|
||||
//process for phase accumulator
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(reset == 1'b1)
|
||||
accu <= 0; //synchronous reset
|
||||
else if(accu_en == 1'b1)
|
||||
accu <= accu + fcw;
|
||||
end
|
||||
//10 msb's of the phase accumulator are used to index the sinewave lookup-table
|
||||
assign lut_index = accu[23:14];
|
||||
//16-bit sine value from lookup table
|
||||
assign dds_sin = rom_memory[lut_index];
|
||||
endmodule
|
104
cpld/tb/testbench_top.v
Normal file
104
cpld/tb/testbench_top.v
Normal file
@ -0,0 +1,104 @@
|
||||
`timescale 1ns/1ps
|
||||
module testbench_top();
|
||||
|
||||
reg rst_n;
|
||||
reg clk32;
|
||||
|
||||
/* TOP ENTRY */
|
||||
// zx_multisound zx_multisound0(
|
||||
// .rst_n(rst_n),
|
||||
// .clk32(clk32),
|
||||
// .cfg(5'b11111),
|
||||
// .a(16'hFFFF),
|
||||
// // .d(8'hFF),
|
||||
// .n_rd(1'b1),
|
||||
// .n_wr(1'b1),
|
||||
// .n_iorq(1'b1),
|
||||
// .n_mreq(1'b1),
|
||||
// .n_m1(1'b1),
|
||||
// .ga(16'hFFFF),
|
||||
// // .gd(8'hFF),
|
||||
// .n_grd(1'b1),
|
||||
// .n_gwr(1'b1),
|
||||
// .n_gm1(1'b1),
|
||||
// .n_gmreq(1'b1),
|
||||
// .n_giorq(1'b1)
|
||||
// );
|
||||
|
||||
/* CLOCKS & RESET */
|
||||
initial begin
|
||||
rst_n = 0;
|
||||
#50 rst_n = 1;
|
||||
end
|
||||
|
||||
always begin
|
||||
clk32 = 0;
|
||||
#15.625 clk32 = 1;
|
||||
#15.625;
|
||||
end
|
||||
|
||||
|
||||
wire [15:0] sine_vol;
|
||||
sine_dds sine_dds_vol(clk32, ~rst_n, 256, sine_vol);
|
||||
wire [15:0] sine_dac;
|
||||
sine_dds sine_dds_dac(clk32, ~rst_n, 1024, sine_dac);
|
||||
|
||||
// wire [5:0] volx = 6'h00;
|
||||
// wire [5:0] volx = 6'h1F;
|
||||
wire [5:0] volx = 6'h3F;
|
||||
// wire [5:0] volx = sine_vol[15:10];
|
||||
// reg [5:0] volx = 6'h3F;
|
||||
// initial begin
|
||||
// #2_000_000 volx = 0;
|
||||
// #2_000_000 volx = 6'h1F;
|
||||
// #2_000_000 volx = 0;
|
||||
// #2_000_000 volx = 6'h3F;
|
||||
// end
|
||||
|
||||
// wire [7:0] dacx = 8'h00;
|
||||
// wire [7:0] dacx = 8'h80;
|
||||
// wire [7:0] dacx = 8'hFF;
|
||||
wire [7:0] dacx = sine_vol[15:8];
|
||||
|
||||
|
||||
wire [7:0] dacx0 = dacx[7]? {~dacx[7],dacx[6:0]} : {dacx[7],~dacx[6:0]};
|
||||
reg [5:0] volx_cnt;
|
||||
reg [7:0] dacx_cnt;
|
||||
wire volx_en = (volx_cnt < volx) || (&volx);
|
||||
wire dacx_cnt7 = dacx_cnt[7];
|
||||
wire dacx7 = dacx[7];
|
||||
wire dacx_out = dacx_cnt[7]? dacx[7] : clk32;
|
||||
always @(negedge clk32 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
volx_cnt <= 0;
|
||||
dacx_cnt <= 0;
|
||||
end
|
||||
else begin
|
||||
volx_cnt <= volx_cnt + 6'd31;
|
||||
if (volx_en)
|
||||
dacx_cnt <= dacx_cnt[6:0] + dacx0[6:0];
|
||||
else
|
||||
dacx_cnt[7] <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
/* TESTBENCH CONTROL */
|
||||
integer fhandle;
|
||||
initial begin
|
||||
fhandle = $fopen("testbench_pwl.txt","w");
|
||||
$timeformat(0, 10, "", 0);
|
||||
$dumpfile("testbench.vcd");
|
||||
$dumpvars;
|
||||
#10_000_000;
|
||||
$fclose(fhandle);
|
||||
$finish;
|
||||
end
|
||||
|
||||
`define SCALE 3.3
|
||||
always @(negedge clk32 or posedge clk32) begin
|
||||
$fwrite(fhandle, "%t %f\n", $time, dacx_out*`SCALE);
|
||||
end
|
||||
|
||||
endmodule
|
Reference in New Issue
Block a user