Yosys logic loop falsely detected - yosys

I've been testing yosys for some use cases.
Version: Yosys 0.7+200 (git sha1 155a80d, gcc-6.3 6.3.0 -fPIC -Os)
I wrote a simple block which converts gray code to binary:
module gray2bin (gray, bin);
parameter WDT = 3;
input [WDT-1:0] gray;
output [WDT-1:0] bin;
assign bin = {gray[WDT-1], bin[WDT-1:1]^gray[WDT-2:0]};
endmodule
This is an acceptable and valid code in verilog, and there is no loop in it.
It passes compilation and synthesis without any warnings in other tools.
But, when I run in yosys the next commands:
read_verilog gray2bin.v
scc
I get that a logic loop was found:
Found an SCC: $xor$gray2bin.v:11$1
Found 1 SCCs in module gray2bin.
Found 1 SCCs.
The next code, which is equivalent, pass the check:
module gray2bin2 (
gray,
bin
);
parameter WDT = 3;
input [WDT-1:0] gray;
output [WDT-1:0] bin;
assign bin[WDT-1] = gray[WDT-1];
genvar i;
generate
for (i = WDT-2; i>=0; i=i-1) begin : gen_serial_xor
assign bin[i] = bin[i+1]^gray[i];
end
endgenerate
endmodule
Am I missing a flag or synthesis option of some kind?

Using word-wide operators this circuit clearly has a loop (generated with yosys -p 'prep; show' gray2bin.v):
You have to synthesize the circuit to a gate-level representation to get a loop-free version (generated with yosys -p 'synth; splitnets -ports; show' gray2bin.v, the call to splitnets is just there for better visualization):

The answer given by CliffordVienna indeed gives a solution, but I also want to clarify that that it's not suitable to all purposes.
My analysis was done for the purpose of formal verification. Since I replaced the prep to synth to solve the falsely identified logic loops, my formal code got optimized. Wires which I've created that were driven only by the assume property pragma, were removed - this made many assertions redundant.
It's not correct to reduce any logic for the purpose of behavioral verification.
Therefore, if the purpose is to prepare a verification database, I suggest not to use the synth command, but to use a subset of commands the synth command executes.
You can find those commands under:
http://www.clifford.at/yosys/cmd_synth.html
In general, I've used all the commands specified in the above link that do not optimize logic:
hierarchy -check
proc
check
wreduce
alumacc
fsm
memory -nomap
memory_map
techmap
abc -fast
hierarchy -check
stat
check
And everything works as expected.

Related

Can I avoid opt_merge from removing a BUF? (Yosys tri-state workaround)

I know yosys has limited tri-state support, but I'm looking for a possible workaround.
The following circuit:
module TBUF2
(
inout SALIDA1,
inout SALIDA2,
input OE,
output C);
assign SALIDA1=OE ? 1'b0 : 1'bZ;
assign SALIDA2=OE ? 1'b0 : 1'bZ;
wire e;
assign e=SALIDA1 & SALIDA2;
assign C=e;
endmodule
Is interpreted as:
TBUF2 parsed tree
Note that when OE is 0 C=SALIDA1 and SALIDA2.
During the opt pass, the opt_merge pass removes $2 mux and generates:
TBUF2 optimized
This breaks the circuit (when OE is 0 then C=SALIDA1). I realize this is because yosys/ABC doesn't really understand the consequences of the "1'z" input.
Is it possible to keep muxes that meet the following criteria?:
1) At least one input is 1'Z
2) Its output drives an inout pin
Here is the script to reproduce it:
read_verilog tbuf2.v
proc
show -format dot -prefix tbuf2_01
opt
show -format dot -prefix tbuf2_02
Convert the tristate buffer $mux cells to $tribuf cells by running the tribuf command after proc and before running any opt commands.

Is it possible to remove clock input variable from the AIGER output?

Consider the example:
read_verilog ./tests/simple/fsm.v
synth -flatten -top fsm_test
abc -g AND
write_aiger -ascii -symbols hoho.aag
The resulting AIGER file contains input variable clk, which is dangling.
Is it possible to avoid introducing such clock input into AIGER?
Thanks.
Not automatically. The following options exist:
Simply use the SystemVerilog $global_clock feature to avoid having a clock input at all. Use always #($global_clock) instead of always #(posedge clk) and then remove the clk input from your design.
Remove the clock input near the end of your synthesis script. I.e. right before calling write_aiger call something like delete -input fsm_test/clk. This will turn the clock signal into a dangling wire internal to the module. You should avoid doing that before running a lot of optimization commands, or you risk Yosys optimizing away all your FFs. But doing that near the end of your script should be fine.
You can combine 2. with mapping your FFs to $ff/$_FF_ cells (the kind of FF cells generated by $global_clock-blocks). The advantage of this approach is that it makes the clk wire truly unused, so there is no risk of optimizations messing with your FFs because they have an undriven clock input. I've now added a dff2ff.v techmap file in commit e7a984a that simplifies this a bit.
Script for option 2:
read_verilog ./tests/simple/fsm.v
synth -flatten -top fsm_test
abc -g AND
delete -input fsm_test/clk
write_aiger -ascii -symbols hoho.aag
Script for option 3 (requires Yosys git commit e7a984a or later):
read_verilog ./tests/simple/fsm.v
hierarchy -top fsm_test
proc
techmap -map +/dff2ff.v
delete fsm_test/clk
synth -flatten
abc -g AND
write_aiger -ascii -symbols hoho.aag

Find and Replace an operation in Verilog using Yosys

I am trying to see if Yosys fits my requirements or no.
What i want to do is to find an operation in Verilog code (e.g. temp = 16*val1 + 8*val2 ) and replace this with another op like ( temp = val1 << 4 + val2 << 3 ).
Which parts i need to learn & use from Yosys? if anyone knows the set of command to use, can he/she please let me know to boost my learning curve ?
Thanks.
For example consider the following verilog input (test.v):
module test(input [7:0] val1, val2, output [7:0] temp);
assign temp = 16*val1 + 8*val2;
endmodule
The command yosys -p 'prep; opt -full; show' test.v will produce the following circuit diagram:
And the output written to the console contains this:
3.1. Executing OPT_EXPR pass (perform const folding).
Replacing multiply-by-16 cell `$mul$test.v:2$1' in module `\test' with shift-by-4.
Replacing multiply-by-8 cell `$mul$test.v:2$2' in module `\test' with shift-by-3.
Replacing $shl cell `$mul$test.v:2$1' (B=3'100, SHR=-4) in module `test' with fixed wiring: { \val1 [3:0] 4'0000 }
Replacing $shl cell `$mul$test.v:2$2' (B=2'11, SHR=-3) in module `test' with fixed wiring: { \val2 [4:0] 3'000 }
The two lines reading Replacing multiply-by-* cell are the transformation you mentioned. The two lines after that replace the constant shift operations with wiring, using {val1[3:0], 4'b0000} and {val2[4:0], 3'b000} as inputs for the adder.
This is done in the opt_expr pass. See passes/opt/opt_expr.cc for its source code to see how it's done.

tcl tcltest unknown option -run

When I run ANY test I get the same message. Here is an example test:
package require tcltest
namespace import -force ::tcltest::*
test foo-1.1 {save 1 in variable name foo} {} {
set foo 1
} {1}
I get the following output:
WARNING: unknown option -run: should be one of -asidefromdir, -constraints, -debug, -errfile, -file, -limitconstraints, -load, -loadfile, -match, -notfile, -outfile, -preservecore, -relateddir, -singleproc, -skip, -testdir, -tmpdir, or -verbose
I've tried multiple tests and nothing seems to work. Does anyone know how to get this working?
Update #1:
The above error was my fault, it was due to it being run in my script. However if I run the following at a command line I got no output:
[root#server1 ~]$ tcl
tcl>package require tcltest
2.3.3
tcl>namespace import -force ::tcltest::*
tcl>test foo-1.1 {save 1 in variable name foo} {expr 1+1} {2}
tcl>echo [test foo-1.1 {save 1 in variable name foo} {expr 1+1} {2}]
tcl>
How do I get it to output pass or fail?
You don't get any output from the test command itself (as long as the test passes, as in the example: if it fails, the command prints a "contents of test case" / "actual result" / "expected result" summary; see also the remark on configuration below). The test statistics are saved internally: you can use the cleanupTests command to print the Total/Passed/Skipped/Failed numbers (that command also resets the counters and does some cleanup).
(When you run runAllTests, it runs test files in child processes, intercepting the output from each file's cleanupTests and adding them up to a grand total.)
The internal statistics collected during testing is available in AFACT undocumented namespace variables like ::tcltest::numTests. If you want to work with the statistics yourself, you can access them before calling cleanupTests, e.g.
parray ::tcltest::numTests
array set myTestData [array get ::tcltest::numTests]
set passed $::tcltest::numTests(Passed)
Look at the source for tcltest in your library to see what variables are available.
The amount of output from the test command is configurable, and you can get output even when the test passes if you add p / pass to the -verbose option. This option can also let you have less output on failure, etc.
You can also create a command called ::tcltest::ReportToMaster which, if it exists, will be called by cleanupTests with the pertinent data as arguments. Doing so seems to suppress both output of statistics and at least most resetting and cleanup. (I didn't go very far in investigating that method.) Be aware that messing about with this is more likely to create trouble than solve problems, but if you are writing your own testing software based on tcltest you might still want to look at it.
Oh, and please use the newer syntax for the test command. It's more verbose, but you'll thank yourself later on if you get started with it.
Obligatory-but-fairly-useless (in this case) documentation link: tcltest

How to access debug information in a running application

I was wondering if it is possible to access debug information in a running application that has been compiled with /DEBUG (Pascal and/or C), in order to retrieve information about structures used in the application.
The application can always ask the debugger to do something using SS$_DEBUG. If you send a list of commands that end with GO then the application will continue running after the debugger does its thing. I've used it to dump a bunch of structures formatted neatly without bothering to write the code.
ANALYZE/IMAGE can be used to examine the debugger data in the image file without running the application.
Although you may not see the nice debugger information, you can always look into a running program's data with ANALYZE/SYSTEM .. SET PROCESS ... EXAMINE ....
The SDA SEARCH command may come in handy to 'find' recognizable morcels of date, like a record that you know the program must have read.
Also check out FORMAT/TYPE=block-type, but to make use of data you'll have to compile your structures into .STB files.
When using SDA, you may want to try run the program yourself interactively in an other session to get sample sample addresses to work from.... easier than a link map!
If you programs use RMS a bunch (mine always do :-), then SDA> SHOW PROC/RMS=(FAB,RAB) may give handy addresses for record and key buffers, allthough those may also we managed by the RTL's and thus not be meaningful to you.
Too long for a comment ...
As far as I know, structure information about elements is not in the global symbol table.
What I did, on Linux, but that should work on VMS/ELF files as well:
$ cat tests.c
struct {
int ii;
short ss;
float ff;
char cc;
double dd;
char bb:1;
void *pp;
} theStruct;
...
$ cc -g -c tests.c
$ ../extruct/extruct
-e-insarg, supply an ELF object file.
Usage: ../extruct/extruct [OPTION]... elf-file variable
Display offset and size of members of the named struct/union variable
extracted from the dwarf info in the elf file.
Options are:
-b bit offsets and bit sizes for all members
-lLEVEL display level for nested structures
-n only the member names
-t print base types
$ ../extruct/extruct -t ./tests.o theStruct
size of theStruct: 0x20
offset size type name
0x0000 0x0004 int ii
0x0004 0x0002 short int ss
0x0008 0x0004 float ff
0x000c 0x0001 char cc
0x0010 0x0008 double dd
0x0018 0x0001 char bb:1
0x001c 0x0004 pp
$