What are the useful attributes that can be used with passes in Yosys? - yosys

What are the most useful attributes that can be used with passes in Yosys?
Also, I was wondering if you could give me an example to set 'keep_hierarchy' for a specific module (namely "counter") using 'setattr'.

The README File contains a list of the most prominent attributes. (Section "Verilog Attributes and non-standard features".)
Regarding keep_hierarchy and setattr: Consider the following example code.
module test(input A, B, output X, Y);
test_and and_inst (.A(A), .B(B), .O(X));
test_xor xor_inst (.A(A), .B(B), .O(Y));
endmodule
module test_and(input A, B, output O);
assign O = A & B;
endmodule
module test_xor(input A, B, output O);
assign O = A ^ B;
endmodule
Obviously the following would just display a schematic with a $and and a $xor gate:
yosys -p 'prep; flatten; opt -purge; show test' test.v
Now we can prevent flatten from flattening and_inst by setting the keep_hierarchy attribute on the cell:
yosys -p 'prep; setattr -set keep_hierarchy 1 test/and_inst; flatten; opt -purge; show test' test.v
Alternatively we can prevent all instances of test_and to be flattened by simply setting the attribute on the module itself:
yosys -p 'prep; setattr -mod -set keep_hierarchy 1 test_and; flatten; opt -purge; show test' test.v

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.

Yosys logic loop falsely detected

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.

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.

How to store a result to a variable in HP OpenVMS DCL?

I want to save the output of a program to a variable.
I use the following approach ,but fail.
$ PIPE RUN TEST | DEFINE/JOB VALUE #SYS$PIPE
$ x = f$logical("VALUE")
I got an error:%DCL-W-MAXPARM, too many parameters - reenter command with fewer parameters
\WORLD\
reference :
How to assign the output of a program to a variable in a DCL com script on VMS?
The usual way to do this is to write the output to a file and read from the file and put that into a DCL symbol (or logical). Although not obvious, you can do this with the PIPE command was well:
$ pipe r 2words
hello world
$ pipe r 2words |(read sys$pipe line ; line=""""+line+"""" ; def/job value &line )
$ sh log value
"VALUE" = "hello world" (LNM$JOB_85AB4440)
$
IF you are able to change the program, add some code to it to write the required values into symbols or logicals (see LIB$ routines)
If you can modify the program, using LIB$SET_SYMBOL in the program defines a DCL symbol (what you are calling a variable) for DCL. That's the cleanest way to do this. If it really needs to be a logical, then there are system calls that define logicals.

Forth as an interactive C program tester

I'm willing to use an interactive language to test some C code from a legacy project. I know a little Forth, but I haven't ever used it in a real world project. I'm looking at pForth right now.
Is it reasonable to use an interactive Forth interpreter to test the behavior of some function in a C program? This C code has lots of structs, pointers to structs, handles and other common structures found in C.
I suppose I'll have to write some glue code to handle the parameter passing and maybe some struct allocation in the Forth side. I want an estimate from someone with experience in this field. Is it worth it?
If you want interactive testing and are targeting embedded platforms, then Forth is definitely a good candidate. You'll always find a Forth implementation that runs on your target platform. Writing one is not even hard either if need be.
Instead of writing glue code specific to your immediate needs, go for a generic purpose Forth to C interface. I use gforth's generic C interface which is very easy to use. For structure handling in Forth, I use an MPE style implementation which is very flexible when it comes to interfacing with C (watch out for proper alignment though, see gforth %align / %allot / nalign).
The definition of generic purpose structure handling words takes about 20 lines of Forth code, same for single linked lists handling or hash tables.
Since you cannot use gforth (POSIX only), write an extension module for your Forth of choice that implements a similar C interface. Just make sure that your Forth and your C interface module uses the same malloc() and free() than the C code you want to test.
With such an interface, you can do everything in Forth by just defining stub words (i.e. map Forth words to C functions and structures).
Here's a sample test session where I call libc's gettimeofday using gforth's C interface.
s" structs.fs" included also structs \ load structure handling code
clear-libs
s" libc" add-lib \ load libc.so. Not really needed for this particular library
c-library libc \ stubs for C functions
\c #include <sys/time.h>
c-function gettimeofday gettimeofday a a -- n ( struct timeval *, struct timezone * -- int )
end-c-library
struct timeval \ stub for struct timeval
8 field: ->tv_sec \ sizeof(time_t) == 8 bytes on my 64bits system
8 field: ->tv_usec
end-struct
timeval buffer: tv
\ now call it (the 0 is for passing NULL for struct timezone *)
tv 0 gettimeofday . \ Return value on the stack. output : 0
tv ->tv_sec # . \ output : 1369841953
Note that tv ->tv_sec is in fact the equivalent of (void *)&tv + offsetof(struct timeval, tv_sec) in C, so it gives you the address of the structure member, so you have to fetch the value with #. Another issue here: since I use a 64 bits Forth where the cell size is 8 bytes, storing/fetching an 8 bytes long is straightforward, but fetching/storing a 4 bytes int will require some special handling. Anyhow, Forth makes this easy: just define special purpose int# and int! words for that.
As you can see, with a good generic purpose C interface you do not need to write any glue code in C, only the Forth stubs for your C functions and structures are needed, but this is really straightforward (and most of it could be automatically generated from your C headers).
Once you're happy with your interactive tests, you can move on to automated tests:
Copy/paste the whole input/output from your interactive test session to a file named testXYZ.log
strip the output (keeping only the input) from your session log and write this to a file named testXYZ.fs
To run the test, pipe testXYZ.fs to your forth interpreter, capture the output and diff it with testXYZ.log.
Since removing output from an interactive session log can be somewhat tedious, you could also start by writing the test script testXYZ.fs then run it and capture the output testXYZ.log, but I prefer starting from an interactive session log.
Et voilĂ  !
For reference, here's the structure handling code that I used in the above example :
\ *****************************************************************************
\ structures handling
\ *****************************************************************************
\ Simple structure definition words. Structure instances are zero initialized.
\
\ usage :
\ struct foo
\ int: ->refCount
\ int: ->value
\ end-struct
\ struct bar
\ int: ->id
\ foo struct: ->foo
\ 16 chars: ->name
\ end-struct
\
\ bar buffer: myBar
\ foo buffer: myFoo
\ 42 myBar ->id !
\ myFoo myBar ->foo !
\ myBar ->name count type
\ 1 myBar ->foo # ->refCount +! \ accessing members of members could use a helper word
: struct ( "name" -- addr 0 ; named structure header )
create here 0 , 0
does>
# ;
\ <field-size> FIELD <field-name>
\ Given a field size on the stack, compiles a word <field-name> that adds the
\ field size to the number on the stack.
: field: ( u1 u2 "name" -- u1+u2 ; u -- u+u2 )
over >r \ save current struct size
: r> ?dup if
postpone literal postpone +
then
postpone ;
+ \ add field size to struct size
; immediate
: end-struct ( addr u -- ; end of structure definition )
swap ! ;
: naligned ( addr1 u -- addr2 ; aligns addr1 to alignment u )
1- tuck + swap invert and ;
\ Typed field helpers
: int: cell naligned cell postpone field: ; immediate
: struct: >r cell naligned r> postpone field: ; immediate
: chars: >r cell naligned r> postpone field: ; immediate
\ with C style alignment
4 constant C_INT_ALIGN
8 constant C_PTR_ALIGN
4 constant C_INT_SIZE
: cint: C_INT_ALIGN naligned C_INT_SIZE postpone field: ; immediate
: cstruct: >r C_PTR_ALIGN naligned r> postpone field: ; immediate
: cchars: >r C_INT_ALIGN naligned r> postpone field: ; immediate
: buffer: ( u -- ; creates a zero-ed buffer of size u )
create here over erase allot ;