aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/ecp5/tests/test_diamond_ffs.py
blob: 1ed85ce8bc364ca2d5e77ffc17838f5ec0e5a873 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import os
import subprocess

if not os.path.exists("work_ff"):
	os.mkdir("work_ff")

modules = []

with open("../cells_ff.vh", "r") as f:
	with open("work_ff/cells_ff_gate.v", "w") as g:
		for line in f:
			if not line.startswith("module"):
				g.write(line)
				continue
			else:
				spidx = line.find(" ")
				bridx = line.find("(")
				modname = line[spidx+1 : bridx]
				g.write("module %s_gate" % modname)
				g.write(line[bridx:])
				inpidx = line.find("input ")
				outpidx = line.find(", output")
				modules.append((modname, [x.strip() for x in line[inpidx+6:outpidx].split(",")]))

with open("work_ff/testbench.v", "w") as f:
	print("""
`timescale 1ns/ 1ps

module testbench;
reg pur = 0, clk, rst, cen, d;

// Needed for Diamond sim models
GSR GSR_INST (.GSR(1'b1));
PUR PUR_INST (.PUR(pur));


initial begin
	$dumpfile("work_ff/ffs.vcd");
	$dumpvars(0, testbench);
	#5;
	pur = 1;
	#95;
	repeat (2500) begin
		{clk, rst, cen, d} = $random;
		#10;
		check_outputs;
		#1;
	end
	$finish;
end
	""", file=f)

	for modname, inputs in modules:
		print("    wire %s_gold_q, %s_gate_q;"  % (modname, modname), file=f)
		portconns = []
		for inp in inputs:
			if inp in ("SCLK", "CK"):
				portconns.append(".%s(clk)" % inp)
			elif inp in ("CD", "PD"):
				portconns.append(".%s(rst)" % inp)
			elif inp == "SP":
				portconns.append(".%s(cen)" % inp)
			elif inp == "D":
				portconns.append(".%s(d)" % inp)
			else:
				assert False
		portconns.append(".Q(%s_gold_q)" % modname)
		print("    %s %s_gold_i (%s);" % (modname, modname, ", ".join(portconns)), file=f)
		portconns[-1] = (".Q(%s_gate_q)" % modname)
		print("    %s_gate %s_gate_i (%s);" % (modname, modname, ", ".join(portconns)), file=f)
		print("", file=f)
	print("    task check_outputs;", file=f)
	print("        begin", file=f)
	print("             if (%s_gold_q != %s_gate_q) $display(\"MISMATCH at %%1t:  %s_gold_q=%%b, %s_gate_q=%%b\", $time, %s_gold_q, %s_gate_q);" %
			(modname, modname, modname, modname, modname, modname), file=f)
	print("        end", file=f)
	print("    endtask", file=f)
	print("endmodule", file=f)

diamond_models = "/usr/local/diamond/3.10_x64/cae_library/simulation/verilog/ecp5u"
subprocess.call(["iverilog", "-s", "testbench", "-o", "work_ff/testbench", "-Dmixed_hdl", "-DNO_INCLUDES", "-y", diamond_models, "work_ff/cells_ff_gate.v", "../cells_sim.v", "work_ff/testbench.v"])
subprocess.call(["vvp", "work_ff/testbench"])
"p">; retime = false; nolutram = false; } void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-top" && argidx+1 < args.size()) { top_opt = "-top " + args[++argidx]; continue; } if (args[argidx] == "-edif" && argidx+1 < args.size()) { edif_file = args[++argidx]; continue; } if (args[argidx] == "-json" && argidx+1 < args.size()) { json_file = args[++argidx]; continue; } if (args[argidx] == "-run" && argidx+1 < args.size()) { size_t pos = args[argidx+1].find(':'); if (pos == std::string::npos) break; run_from = args[++argidx].substr(0, pos); run_to = args[argidx].substr(pos+1); continue; } if (args[argidx] == "-noflatten") { flatten = false; continue; } if (args[argidx] == "-nolutram") { nolutram = true; continue; } if (args[argidx] == "-retime") { retime = true; continue; } break; } extra_args(args, argidx, design); if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); log_header(design, "Executing SYNTH_ANLOGIC pass.\n"); log_push(); run_script(design, run_from, run_to); log_pop(); } void script() override { if (check_label("begin")) { run("read_verilog -lib +/anlogic/cells_sim.v +/anlogic/eagle_bb.v"); run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str())); } if (flatten && check_label("flatten", "(unless -noflatten)")) { run("proc"); run("flatten"); run("tribuf -logic"); run("deminout"); } if (check_label("coarse")) { run("synth -run coarse"); } if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) { run("memory_bram -rules +/anlogic/lutrams.txt"); run("techmap -map +/anlogic/lutrams_map.v"); run("setundef -zero -params t:EG_LOGIC_DRAM16X4"); } if (check_label("map_ffram")) { run("opt -fast -mux_undef -undriven -fine"); run("memory_map"); run("opt -undriven -fine"); } if (check_label("map_gates")) { run("techmap -map +/techmap.v -map +/anlogic/arith_map.v"); run("opt -fast"); if (retime || help_mode) run("abc -dff -D 1", "(only if -retime)"); } if (check_label("map_ffs")) { run("dfflegalize -cell $_DFFE_P??P_ r -cell $_SDFFE_P??P_ r -cell $_DLATCH_N??_ r"); run("techmap -D NO_LUT -map +/anlogic/cells_map.v"); run("opt_expr -mux_undef"); run("simplemap"); } if (check_label("map_luts")) { run("abc -lut 4:6"); run("clean"); } if (check_label("map_cells")) { run("techmap -map +/anlogic/cells_map.v"); run("clean"); } if (check_label("map_anlogic")) { run("anlogic_fixcarry"); run("anlogic_eqn"); } if (check_label("check")) { run("hierarchy -check"); run("stat"); run("check -noinit"); } if (check_label("edif")) { if (!edif_file.empty() || help_mode) run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str())); } if (check_label("json")) { if (!json_file.empty() || help_mode) run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str())); } } } SynthAnlogicPass; PRIVATE_NAMESPACE_END