mirror of https://github.com/YosysHQ/yosys.git
Switching example synth to fifo
Fifo code based on SBY quick start. Instead of showing the full design we are (currently) focusing on a single output (rdata), using `%ci*` to get the subcircuit it relies on.
This commit is contained in:
parent
80c78aaad6
commit
742ec78ca3
|
@ -1,15 +0,0 @@
|
||||||
PROGRAM_PREFIX :=
|
|
||||||
|
|
||||||
YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys
|
|
||||||
|
|
||||||
DOTS = control_hier.dot control_proc.dot
|
|
||||||
DOTS += example_hier.dot
|
|
||||||
|
|
||||||
dots: $(DOTS) example.out
|
|
||||||
|
|
||||||
$(DOTS) example.out: example.v example.ys
|
|
||||||
$(YOSYS) example.ys -l example.out -Q
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -f *.dot
|
|
|
@ -1,147 +0,0 @@
|
||||||
|
|
||||||
-- Executing script file `example.ys' --
|
|
||||||
echo on
|
|
||||||
|
|
||||||
yosys> read_verilog -defer example.v
|
|
||||||
|
|
||||||
1. Executing Verilog-2005 frontend: example.v
|
|
||||||
Parsing Verilog input from `example.v' to AST representation.
|
|
||||||
Storing AST representation for module `$abstract\example'.
|
|
||||||
Storing AST representation for module `$abstract\control'.
|
|
||||||
Storing AST representation for module `$abstract\data'.
|
|
||||||
Successfully finished Verilog frontend.
|
|
||||||
|
|
||||||
yosys> hierarchy -top control
|
|
||||||
|
|
||||||
2. Executing HIERARCHY pass (managing design hierarchy).
|
|
||||||
|
|
||||||
3. Executing AST frontend in derive mode using pre-parsed AST for module `\control'.
|
|
||||||
Generating RTLIL representation for module `\control'.
|
|
||||||
|
|
||||||
3.1. Analyzing design hierarchy..
|
|
||||||
Top module: \control
|
|
||||||
|
|
||||||
3.2. Analyzing design hierarchy..
|
|
||||||
Top module: \control
|
|
||||||
Removing unused module `$abstract\data'.
|
|
||||||
Removing unused module `$abstract\control'.
|
|
||||||
Removing unused module `$abstract\example'.
|
|
||||||
Removed 3 unused modules.
|
|
||||||
|
|
||||||
yosys> show -notitle -format dot -prefix control_hier
|
|
||||||
|
|
||||||
4. Generating Graphviz representation of design.
|
|
||||||
Writing dot description to `control_hier.dot'.
|
|
||||||
Dumping module control to page 1.
|
|
||||||
|
|
||||||
yosys> proc
|
|
||||||
|
|
||||||
5. Executing PROC pass (convert processes to netlists).
|
|
||||||
|
|
||||||
yosys> proc_clean
|
|
||||||
|
|
||||||
5.1. Executing PROC_CLEAN pass (remove empty switches from decision trees).
|
|
||||||
Cleaned up 0 empty switches.
|
|
||||||
|
|
||||||
yosys> proc_rmdead
|
|
||||||
|
|
||||||
5.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees).
|
|
||||||
Marked 1 switch rules as full_case in process $proc$example.v:43$1 in module control.
|
|
||||||
Removed a total of 0 dead cases.
|
|
||||||
|
|
||||||
yosys> proc_prune
|
|
||||||
|
|
||||||
5.3. Executing PROC_PRUNE pass (remove redundant assignments in processes).
|
|
||||||
Removed 1 redundant assignment.
|
|
||||||
Promoted 0 assignments to connections.
|
|
||||||
|
|
||||||
yosys> proc_init
|
|
||||||
|
|
||||||
5.4. Executing PROC_INIT pass (extract init attributes).
|
|
||||||
|
|
||||||
yosys> proc_arst
|
|
||||||
|
|
||||||
5.5. Executing PROC_ARST pass (detect async resets in processes).
|
|
||||||
|
|
||||||
yosys> proc_rom
|
|
||||||
|
|
||||||
5.6. Executing PROC_ROM pass (convert switches to ROMs).
|
|
||||||
Converted 0 switches.
|
|
||||||
<suppressed ~2 debug messages>
|
|
||||||
|
|
||||||
yosys> proc_mux
|
|
||||||
|
|
||||||
5.7. Executing PROC_MUX pass (convert decision trees to multiplexers).
|
|
||||||
Creating decoders for process `\control.$proc$example.v:43$1'.
|
|
||||||
1/2: $0\addr[7:0]
|
|
||||||
2/2: $0\state[1:0]
|
|
||||||
|
|
||||||
yosys> proc_dlatch
|
|
||||||
|
|
||||||
5.8. Executing PROC_DLATCH pass (convert process syncs to latches).
|
|
||||||
|
|
||||||
yosys> proc_dff
|
|
||||||
|
|
||||||
5.9. Executing PROC_DFF pass (convert process syncs to FFs).
|
|
||||||
Creating register for signal `\control.\state' using process `\control.$proc$example.v:43$1'.
|
|
||||||
created $dff cell `$procdff$12' with positive edge clock.
|
|
||||||
Creating register for signal `\control.\addr' using process `\control.$proc$example.v:43$1'.
|
|
||||||
created $dff cell `$procdff$13' with positive edge clock.
|
|
||||||
|
|
||||||
yosys> proc_memwr
|
|
||||||
|
|
||||||
5.10. Executing PROC_MEMWR pass (convert process memory writes to cells).
|
|
||||||
|
|
||||||
yosys> proc_clean
|
|
||||||
|
|
||||||
5.11. Executing PROC_CLEAN pass (remove empty switches from decision trees).
|
|
||||||
Found and cleaned up 2 empty switches in `\control.$proc$example.v:43$1'.
|
|
||||||
Removing empty process `control.$proc$example.v:43$1'.
|
|
||||||
Cleaned up 2 empty switches.
|
|
||||||
|
|
||||||
yosys> opt_expr -keepdc
|
|
||||||
|
|
||||||
5.12. Executing OPT_EXPR pass (perform const folding).
|
|
||||||
Optimizing module control.
|
|
||||||
|
|
||||||
yosys> show -notitle -format dot -prefix control_proc
|
|
||||||
|
|
||||||
6. Generating Graphviz representation of design.
|
|
||||||
Writing dot description to `control_proc.dot'.
|
|
||||||
Dumping module control to page 1.
|
|
||||||
|
|
||||||
yosys> design -reset
|
|
||||||
|
|
||||||
yosys> read_verilog example.v
|
|
||||||
|
|
||||||
7. Executing Verilog-2005 frontend: example.v
|
|
||||||
Parsing Verilog input from `example.v' to AST representation.
|
|
||||||
Generating RTLIL representation for module `\example'.
|
|
||||||
Generating RTLIL representation for module `\control'.
|
|
||||||
Generating RTLIL representation for module `\data'.
|
|
||||||
Successfully finished Verilog frontend.
|
|
||||||
|
|
||||||
yosys> hierarchy -check -top example
|
|
||||||
|
|
||||||
8. Executing HIERARCHY pass (managing design hierarchy).
|
|
||||||
|
|
||||||
8.1. Analyzing design hierarchy..
|
|
||||||
Top module: \example
|
|
||||||
Used module: \data
|
|
||||||
Used module: \control
|
|
||||||
|
|
||||||
8.2. Analyzing design hierarchy..
|
|
||||||
Top module: \example
|
|
||||||
Used module: \data
|
|
||||||
Used module: \control
|
|
||||||
Removed 0 unused modules.
|
|
||||||
|
|
||||||
yosys> show -notitle -format dot -prefix example_hier example
|
|
||||||
|
|
||||||
9. Generating Graphviz representation of design.
|
|
||||||
Writing dot description to `example_hier.dot'.
|
|
||||||
Dumping module example to page 1.
|
|
||||||
|
|
||||||
End of script. Logfile hash: b45465606c, CPU: user 0.01s system 0.00s, MEM: 11.86 MB peak
|
|
||||||
Yosys 0.35+39 (git sha1 0cd4a10c8, clang 10.0.0-4ubuntu1 -fPIC -Os)
|
|
||||||
Time spent: 37% 4x read_verilog (0 sec), 23% 3x show (0 sec), ...
|
|
|
@ -1,76 +0,0 @@
|
||||||
module example (
|
|
||||||
input clk,
|
|
||||||
input rst,
|
|
||||||
input inc,
|
|
||||||
input [7:0] a,
|
|
||||||
input [7:0] b,
|
|
||||||
output [15:0] c
|
|
||||||
);
|
|
||||||
|
|
||||||
wire [1:0] state;
|
|
||||||
wire [7:0] addr;
|
|
||||||
|
|
||||||
control ctrl (
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst),
|
|
||||||
.inc(inc),
|
|
||||||
.addr_o(addr),
|
|
||||||
.state_o(state)
|
|
||||||
);
|
|
||||||
|
|
||||||
data dat (
|
|
||||||
.clk(clk),
|
|
||||||
.addr_i(addr),
|
|
||||||
.state_i(state),
|
|
||||||
.a(a),
|
|
||||||
.b(b),
|
|
||||||
.c(c)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
module control (
|
|
||||||
input clk,
|
|
||||||
input rst,
|
|
||||||
input inc,
|
|
||||||
output [7:0] addr_o,
|
|
||||||
output [1:0] state_o
|
|
||||||
);
|
|
||||||
|
|
||||||
reg [1:0] state;
|
|
||||||
reg [7:0] addr;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
if (rst) begin
|
|
||||||
state <= 2'b00;
|
|
||||||
addr <= 0;
|
|
||||||
end else begin
|
|
||||||
if (inc) state <= state + 1'b1;
|
|
||||||
addr <= addr + 1'b1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule //control
|
|
||||||
|
|
||||||
module data (
|
|
||||||
input clk,
|
|
||||||
input [7:0] addr_i,
|
|
||||||
input [1:0] state_i,
|
|
||||||
input [7:0] a,
|
|
||||||
input [7:0] b,
|
|
||||||
output reg [15:0] c
|
|
||||||
);
|
|
||||||
|
|
||||||
reg [15:0] mem[255:0];
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
case (state_i)
|
|
||||||
2'b00: mem[addr_i] <= a*b;
|
|
||||||
2'b01: mem[addr_i] <= a+b;
|
|
||||||
2'b10: mem[addr_i] <= a-b;
|
|
||||||
2'b11: mem[addr_i] <= addr_i;
|
|
||||||
endcase
|
|
||||||
c <= mem[addr_i];
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule //data
|
|
|
@ -1,17 +0,0 @@
|
||||||
# turn command echoes on to use the log output as a console session
|
|
||||||
echo on
|
|
||||||
|
|
||||||
# ========================================================
|
|
||||||
read_verilog -defer example.v
|
|
||||||
hierarchy -top control
|
|
||||||
show -notitle -format dot -prefix control_hier
|
|
||||||
|
|
||||||
# ========================================================
|
|
||||||
proc
|
|
||||||
show -notitle -format dot -prefix control_proc
|
|
||||||
|
|
||||||
# ========================================================
|
|
||||||
design -reset
|
|
||||||
read_verilog example.v
|
|
||||||
hierarchy -check -top example
|
|
||||||
show -notitle -format dot -prefix example_hier example
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
PROGRAM_PREFIX :=
|
||||||
|
|
||||||
|
YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys
|
||||||
|
|
||||||
|
DOTS = addr_gen_hier.dot addr_gen_proc.dot
|
||||||
|
DOTS += rdata_proc.dot rdata_flat.dot
|
||||||
|
DOTS += fifo_flat.dot fifo_synth.dot
|
||||||
|
|
||||||
|
dots: $(DOTS) fifo.out
|
||||||
|
|
||||||
|
$(DOTS) fifo.out: fifo.v fifo.ys
|
||||||
|
$(YOSYS) fifo.ys -l fifo.out -Q
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -f *.dot
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,73 @@
|
||||||
|
// address generator/counter
|
||||||
|
module addr_gen
|
||||||
|
#( parameter MAX_DATA=256
|
||||||
|
) ( input en, clk, rst,
|
||||||
|
output reg [AWIDTH-1:0] addr
|
||||||
|
);
|
||||||
|
localparam AWIDTH = $clog2(MAX_DATA);
|
||||||
|
|
||||||
|
initial addr <= 0;
|
||||||
|
|
||||||
|
// async reset
|
||||||
|
// increment address when enabled
|
||||||
|
always @(posedge clk or posedge rst)
|
||||||
|
if (rst)
|
||||||
|
addr <= 0;
|
||||||
|
else if (en) begin
|
||||||
|
if (addr == MAX_DATA-1)
|
||||||
|
addr <= 0;
|
||||||
|
else
|
||||||
|
addr <= addr + 1;
|
||||||
|
end
|
||||||
|
endmodule //addr_gen
|
||||||
|
|
||||||
|
// Define our top level fifo entity
|
||||||
|
module fifo
|
||||||
|
#( parameter MAX_DATA=256
|
||||||
|
) ( input wen, ren, clk, rst,
|
||||||
|
input [7:0] wdata,
|
||||||
|
output reg [7:0] rdata,
|
||||||
|
output reg [AWIDTH:0] count
|
||||||
|
);
|
||||||
|
localparam AWIDTH = $clog2(MAX_DATA);
|
||||||
|
|
||||||
|
// fifo storage
|
||||||
|
// sync read before write
|
||||||
|
wire [AWIDTH-1:0] waddr, raddr;
|
||||||
|
reg [7:0] data [MAX_DATA-1:0];
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (wen)
|
||||||
|
data[waddr] <= wdata;
|
||||||
|
rdata <= data[raddr];
|
||||||
|
end // storage
|
||||||
|
|
||||||
|
// addr_gen for both write and read addresses
|
||||||
|
addr_gen #(.MAX_DATA(MAX_DATA))
|
||||||
|
fifo_writer (
|
||||||
|
.en (wen),
|
||||||
|
.clk (clk),
|
||||||
|
.rst (rst),
|
||||||
|
.addr (waddr)
|
||||||
|
);
|
||||||
|
|
||||||
|
addr_gen #(.MAX_DATA(MAX_DATA))
|
||||||
|
fifo_reader (
|
||||||
|
.en (ren),
|
||||||
|
.clk (clk),
|
||||||
|
.rst (rst),
|
||||||
|
.addr (raddr)
|
||||||
|
);
|
||||||
|
|
||||||
|
// status signals
|
||||||
|
initial count <= 0;
|
||||||
|
|
||||||
|
always @(posedge clk or posedge rst) begin
|
||||||
|
if (rst)
|
||||||
|
count <= 0;
|
||||||
|
else if (wen && !ren)
|
||||||
|
count <= count + 1;
|
||||||
|
else if (ren && !wen)
|
||||||
|
count <= count - 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,39 @@
|
||||||
|
# ========================================================
|
||||||
|
# throw in some extra text to match what we expect if we were opening an
|
||||||
|
# interactive terminal
|
||||||
|
log $ yosys fifo.v
|
||||||
|
log
|
||||||
|
log -- Parsing `fifo.v' using frontend ` -vlog2k' --
|
||||||
|
read_verilog -defer fifo.v
|
||||||
|
|
||||||
|
# turn command echoes on to use the log output as a console session
|
||||||
|
echo on
|
||||||
|
hierarchy -top addr_gen
|
||||||
|
show -notitle -format dot -prefix addr_gen_hier
|
||||||
|
|
||||||
|
# ========================================================
|
||||||
|
proc
|
||||||
|
show -notitle -format dot -prefix addr_gen_proc
|
||||||
|
|
||||||
|
# ========================================================
|
||||||
|
design -reset
|
||||||
|
read_verilog fifo.v
|
||||||
|
hierarchy -check -top fifo
|
||||||
|
proc
|
||||||
|
show -notitle -format dot -prefix rdata_proc o:rdata %ci*
|
||||||
|
|
||||||
|
# ========================================================
|
||||||
|
|
||||||
|
flatten
|
||||||
|
show -notitle -format dot -prefix rdata_flat o:rdata %ci*
|
||||||
|
|
||||||
|
# ========================================================
|
||||||
|
|
||||||
|
opt_clean
|
||||||
|
show -notitle -format dot -prefix fifo_flat
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog fifo.v
|
||||||
|
synth_ice40 -dsp -top fifo
|
||||||
|
show -notitle -format dot -prefix fifo_synth
|
||||||
|
stat
|
|
@ -23,37 +23,29 @@ First, let's quickly look at the design we'll be synthesizing:
|
||||||
|
|
||||||
.. todo:: reconsider including the whole (~77 line) design like this
|
.. todo:: reconsider including the whole (~77 line) design like this
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/example_synth/example.v
|
.. literalinclude:: /code_examples/fifo/fifo.v
|
||||||
:language: Verilog
|
:language: Verilog
|
||||||
:linenos:
|
:linenos:
|
||||||
:caption: ``example.v``
|
:caption: ``fifo.v``
|
||||||
:name: example-v
|
:name: fifo-v
|
||||||
|
|
||||||
.. todo:: example.v description
|
.. todo:: fifo.v description
|
||||||
|
|
||||||
Loading the design
|
Loading the design
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Let's load the design into Yosys. From the command line, we can call ``yosys
|
Let's load the design into Yosys. From the command line, we can call ``yosys
|
||||||
example.v``. This will open an interactive Yosys shell session and immediately
|
fifo.v``. This will open an interactive Yosys shell session and immediately
|
||||||
parse the code from ``example.v`` and convert it into an Abstract Syntax Tree
|
parse the code from ``fifo.v`` and convert it into an Abstract Syntax Tree
|
||||||
(AST). If you are interested in how this happens, there is more information in
|
(AST). If you are interested in how this happens, there is more information in
|
||||||
the document, :doc:`/yosys_internals/flow/verilog_frontend`. For now, suffice
|
the document, :doc:`/yosys_internals/flow/verilog_frontend`. For now, suffice
|
||||||
it to say that we do this to simplify further processing of the design. You
|
it to say that we do this to simplify further processing of the design. You
|
||||||
should see something like the following:
|
should see something like the following:
|
||||||
|
|
||||||
.. code:: console
|
.. literalinclude:: /code_examples/fifo/fifo.out
|
||||||
|
:language: console
|
||||||
$ yosys example.v
|
:start-at: $ yosys fifo.v
|
||||||
|
:end-before: echo on
|
||||||
-- Parsing `example.v' using frontend ` -vlog2k' --
|
|
||||||
|
|
||||||
1. Executing Verilog-2005 frontend: example.v
|
|
||||||
Parsing Verilog input from `example.v' to AST representation.
|
|
||||||
Storing AST representation for module `$abstract\example'.
|
|
||||||
Storing AST representation for module `$abstract\control'.
|
|
||||||
Storing AST representation for module `$abstract\data'.
|
|
||||||
Successfully finished Verilog frontend.
|
|
||||||
|
|
||||||
.. seealso:: Advanced usage docs for
|
.. seealso:: Advanced usage docs for
|
||||||
:doc:`/using_yosys/more_scripting/load_design`
|
:doc:`/using_yosys/more_scripting/load_design`
|
||||||
|
@ -62,10 +54,10 @@ Elaboration
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
Now that we are in the interactive shell, we can call Yosys commands directly.
|
Now that we are in the interactive shell, we can call Yosys commands directly.
|
||||||
Our overall goal is to call :yoscrypt:`synth_ice40 -top example`, but for now we
|
Our overall goal is to call :yoscrypt:`synth_ice40 -top fifo`, but for now we
|
||||||
can run each of the commands individually for a better sense of how each part
|
can run each of the commands individually for a better sense of how each part
|
||||||
contributes to the flow. We will also start with just a single module;
|
contributes to the flow. We will also start with just a single module;
|
||||||
``control``.
|
``addr_gen``.
|
||||||
|
|
||||||
At the bottom of the :cmd:ref:`help` output for
|
At the bottom of the :cmd:ref:`help` output for
|
||||||
:cmd:ref:`synth_ice40` is the complete list of commands called by this script.
|
:cmd:ref:`synth_ice40` is the complete list of commands called by this script.
|
||||||
|
@ -86,20 +78,20 @@ design. PLLs are a common example of this, where we might need to reference
|
||||||
later. Since our simple design doesn't use any of these IP blocks, we can safely
|
later. Since our simple design doesn't use any of these IP blocks, we can safely
|
||||||
skip this command.
|
skip this command.
|
||||||
|
|
||||||
The control module
|
The addr_gen module
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Since we're just getting started, let's instead begin with :yoscrypt:`hierarchy
|
Since we're just getting started, let's instead begin with :yoscrypt:`hierarchy
|
||||||
-top control`. This command declares that the top level module is ``control``,
|
-top addr_gen`. This command declares that the top level module is ``addr_gen``,
|
||||||
and everything else can be discarded.
|
and everything else can be discarded.
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/example_synth/example.v
|
.. literalinclude:: /code_examples/fifo/fifo.v
|
||||||
:language: Verilog
|
:language: Verilog
|
||||||
:start-at: module control
|
:start-at: module addr_gen
|
||||||
:end-at: endmodule //control
|
:end-at: endmodule //addr_gen
|
||||||
:lineno-match:
|
:lineno-match:
|
||||||
:caption: ``control`` module source
|
:caption: ``addr_gen`` module source
|
||||||
:name: control-v
|
:name: addr_gen-v
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -108,26 +100,26 @@ and everything else can be discarded.
|
||||||
|
|
||||||
.. use doscon for a console-like display that supports the `yosys> [command]` format.
|
.. use doscon for a console-like display that supports the `yosys> [command]` format.
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/example_synth/example.out
|
.. literalinclude:: /code_examples/fifo/fifo.out
|
||||||
:language: doscon
|
:language: doscon
|
||||||
:start-at: yosys> hierarchy -top control
|
:start-at: yosys> hierarchy -top addr_gen
|
||||||
:end-before: yosys> show
|
:end-before: yosys> show
|
||||||
:caption: :yoscrypt:`hierarchy -top control` output
|
:caption: :yoscrypt:`hierarchy -top addr_gen` output
|
||||||
|
|
||||||
Our ``control`` circuit now looks like this:
|
Our ``addr_gen`` circuit now looks like this:
|
||||||
|
|
||||||
.. figure:: /_images/code_examples/example_synth/control_hier.*
|
.. figure:: /_images/code_examples/fifo/addr_gen_hier.*
|
||||||
:class: width-helper
|
:class: width-helper
|
||||||
:name: control_hier
|
:name: addr_gen_hier
|
||||||
|
|
||||||
``control`` module after :cmd:ref:`hierarchy`
|
``addr_gen`` module after :cmd:ref:`hierarchy`
|
||||||
|
|
||||||
Notice that block that says "PROC" in :ref:`control_hier`? Simple operations
|
Notice that block that says "PROC" in :ref:`addr_gen_hier`? Simple operations
|
||||||
like ``addr + 1'b1`` can be extracted from our ``always @`` block in
|
like ``addr + 1`` and ``addr == MAX_DATA-1`` can be extracted from our ``always
|
||||||
:ref:`control-v`. This gives us the two ``$add`` cells we see. But control
|
@`` block in :ref:`addr_gen-v`. This gives us the ``$add`` and ``$eq`` cells we
|
||||||
logic (like the ``if .. else``) and memory elements (like the ``addr <= 0``) are
|
see. But control logic (like the ``if .. else``) and memory elements (like the
|
||||||
not so straightforward. To handle these, let us now introduce the next command:
|
``addr <= 0``) are not so straightforward. To handle these, let us now introduce
|
||||||
:doc:`/cmd/proc`.
|
the next command: :doc:`/cmd/proc`.
|
||||||
|
|
||||||
:cmd:ref:`proc` is a macro command like :cmd:ref:`synth_ice40`. Rather than
|
:cmd:ref:`proc` is a macro command like :cmd:ref:`synth_ice40`. Rather than
|
||||||
modifying the design directly, it instead calls a series of other commands. In
|
modifying the design directly, it instead calls a series of other commands. In
|
||||||
|
@ -135,68 +127,81 @@ the case of :cmd:ref:`proc`, these sub-commands work to convert the behavioral
|
||||||
logic of processes into multiplexers and registers. Let's see what happens when
|
logic of processes into multiplexers and registers. Let's see what happens when
|
||||||
we run it.
|
we run it.
|
||||||
|
|
||||||
.. figure:: /_images/code_examples/example_synth/control_proc.*
|
.. figure:: /_images/code_examples/fifo/addr_gen_proc.*
|
||||||
:class: width-helper
|
:class: width-helper
|
||||||
|
:name: addr_gen_proc
|
||||||
|
|
||||||
``control`` module after :cmd:ref:`proc`
|
``addr_gen`` module after :cmd:ref:`proc`
|
||||||
|
|
||||||
The ``if`` statements are now modeled with ``$mux`` cells, while the registers
|
The ``if`` statements are now modeled with ``$mux`` cells, while the register
|
||||||
use ``$dff`` cells. If we look at the terminal output we can also see all of
|
uses an ``$adff`` cells. If we look at the terminal output we can also see all
|
||||||
the different ``proc_*`` commands being called. We will look at each of these
|
of the different ``proc_*`` commands being called. We will look at each of
|
||||||
in more detail in :doc:`/using_yosys/synthesis/proc`.
|
these in more detail in :doc:`/using_yosys/synthesis/proc`.
|
||||||
|
|
||||||
|
.. todo:: consider a brief glossary for terms like adff
|
||||||
|
|
||||||
The full example
|
The full example
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Let's now go back and check on our full design by using :yoscrypt:`hierarchy
|
Let's now go back and check on our full design by using :yoscrypt:`hierarchy
|
||||||
-check -top example`. By passing the ``-check`` option there we are also
|
-check -top fifo`. By passing the ``-check`` option there we are also
|
||||||
telling the :cmd:ref:`hierarchy` command that if the design includes any
|
telling the :cmd:ref:`hierarchy` command that if the design includes any
|
||||||
non-blackbox modules without an implementation it should return an error.
|
non-blackbox modules without an implementation it should return an error.
|
||||||
|
|
||||||
Note that if we tried to run this command now then we would get an error. This
|
Note that if we tried to run this command now then we would get an error. This
|
||||||
is because we already removed all of the modules other than ``control``. We
|
is because we already removed all of the modules other than ``addr_gen``. We
|
||||||
could restart our shell session, but instead let's use two new commands:
|
could restart our shell session, but instead let's use two new commands:
|
||||||
|
|
||||||
- :doc:`/cmd/design`, and
|
- :doc:`/cmd/design`, and
|
||||||
- :doc:`/cmd/read_verilog`.
|
- :doc:`/cmd/read_verilog`.
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/example_synth/example.out
|
.. literalinclude:: /code_examples/fifo/fifo.out
|
||||||
:language: doscon
|
:language: doscon
|
||||||
:start-at: design -reset
|
:start-at: design -reset
|
||||||
:end-before: yosys> show
|
:end-before: yosys> proc
|
||||||
:caption: reloading ``example.v`` and running :yoscrypt:`hierarchy -check -top example`
|
:caption: reloading ``fifo.v`` and running :yoscrypt:`hierarchy -check -top fifo`
|
||||||
|
|
||||||
Notice how this time we didn't see any of those `$abstract` modules? That's
|
Notice how this time we didn't see any of those `$abstract` modules? That's
|
||||||
because when we ran ``yosys example.v``, the first command Yosys called was
|
because when we ran ``yosys fifo.v``, the first command Yosys called was
|
||||||
:yoscrypt:`read_verilog -defer example.v`. The ``-defer`` option there tells
|
:yoscrypt:`read_verilog -defer fifo.v`. The ``-defer`` option there tells
|
||||||
:cmd:ref:`read_verilog` only read the abstract syntax tree and defer actual
|
:cmd:ref:`read_verilog` only read the abstract syntax tree and defer actual
|
||||||
compilation to a later :cmd:ref:`hierarchy` command. This is useful in cases
|
compilation to a later :cmd:ref:`hierarchy` command. This is useful in cases
|
||||||
where the default parameters of modules yield invalid or not synthesizable code,
|
where the default parameters of modules yield invalid code which is not
|
||||||
which is why Yosys does this automatically and is one of the reasons why
|
synthesizable. This is why Yosys defers compilation automatically and is one of
|
||||||
hierarchy should always be the first command after loading the design. If we
|
the reasons why hierarchy should always be the first command after loading the
|
||||||
know that our design won't run into this issue, we can skip the ``-defer``.
|
design. If we know that our design won't run into this issue, we can skip the
|
||||||
|
``-defer``.
|
||||||
|
|
||||||
|
.. TODO:: more on why :cmd:ref:`hierarchy` is important
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The number before a command's output increments with each command run. Don't
|
The number before a command's output increments with each command run. Don't
|
||||||
worry if your numbers don't match ours! The output you are seeing comes from
|
worry if your numbers don't match ours! The output you are seeing comes from
|
||||||
the same script that was used to generate the images in this document,
|
the same script that was used to generate the images in this document,
|
||||||
included in the source as ``example.ys``. There are extra commands being run
|
included in the source as ``fifo.ys``. There are extra commands being run
|
||||||
which you don't see, but feel free to try them yourself, or play around with
|
which you don't see, but feel free to try them yourself, or play around with
|
||||||
different commands. You can always start over with a clean slate by calling
|
different commands. You can always start over with a clean slate by calling
|
||||||
``exit`` or hitting ``ctrl+c`` (i.e. SIGINT) and re-launching the Yosys
|
``exit`` or hitting ``ctrl+c`` (i.e. SIGINT) and re-launching the Yosys
|
||||||
interactive terminal.
|
interactive terminal.
|
||||||
|
|
||||||
.. figure:: /_images/code_examples/example_synth/example_hier.*
|
We can also run :cmd:ref:`proc` now to finish off the full :ref:`synth_begin`.
|
||||||
|
Because the design schematic is quite large, we will be showing just the data
|
||||||
|
path for the ``rdata`` output. If you would like to see the entire design for
|
||||||
|
yourself, you can do so with :doc:`/cmd/show`. Note that the :cmd:ref:`show`
|
||||||
|
command only works with a single module, so you may need to call it with
|
||||||
|
:yoscrypt:`show fifo`.
|
||||||
|
|
||||||
|
.. figure:: /_images/code_examples/fifo/rdata_proc.*
|
||||||
:class: width-helper
|
:class: width-helper
|
||||||
:name: example_hier
|
:name: rdata_proc
|
||||||
|
|
||||||
``example`` module after :cmd:ref:`hierarchy`
|
``rdata`` output after :cmd:ref:`proc`
|
||||||
|
|
||||||
We can also run :cmd:ref:`proc` now, although we won't actually see any change
|
The ``fifo_reader`` block we can see there is the same as the
|
||||||
in this top view.
|
:ref:`addr_gen_proc` that we looked at earlier.
|
||||||
|
|
||||||
.. TODO:: more on why :cmd:ref:`hierarchy` is important
|
.. TODO:: comment on ``$memrd``
|
||||||
|
|
||||||
.. seealso:: Advanced usage docs for
|
.. seealso:: Advanced usage docs for
|
||||||
:doc:`/using_yosys/synthesis/proc`
|
:doc:`/using_yosys/synthesis/proc`
|
||||||
|
@ -215,12 +220,14 @@ In :cmd:ref:`synth_ice40` we get these:
|
||||||
:name: synth_flatten
|
:name: synth_flatten
|
||||||
:caption: ``flatten`` section
|
:caption: ``flatten`` section
|
||||||
|
|
||||||
First off is :cmd:ref:`synth_flatten`. Flattening the design like this can
|
First off is :cmd:ref:`flatten`. Flattening the design like this can
|
||||||
allow for optimizations between modules which would otherwise be missed. We
|
allow for optimizations between modules which would otherwise be missed.
|
||||||
will skip this command for now because it makes the design schematic quite
|
|
||||||
large. If you would like to see for yourself, you can do so with
|
.. figure:: /_images/code_examples/fifo/rdata_flat.*
|
||||||
:doc:`/cmd/show`. Note that the :cmd:ref:`show` command only works with a
|
:class: width-helper
|
||||||
single module, so you may need to call it with :yoscrypt:`show example`.
|
:name: rdata_flat
|
||||||
|
|
||||||
|
``rdata`` module after :cmd:ref:`flatten`
|
||||||
|
|
||||||
Depending on the target architecture, we might also see commands such as
|
Depending on the target architecture, we might also see commands such as
|
||||||
:cmd:ref:`tribuf` with the ``-logic`` option and :cmd:ref:`deminout`. These
|
:cmd:ref:`tribuf` with the ``-logic`` option and :cmd:ref:`deminout`. These
|
||||||
|
@ -244,6 +251,7 @@ In the iCE40 flow we get all the following commands:
|
||||||
|
|
||||||
.. literalinclude:: /cmd/synth_ice40.rst
|
.. literalinclude:: /cmd/synth_ice40.rst
|
||||||
:language: yoscrypt
|
:language: yoscrypt
|
||||||
|
:linenos:
|
||||||
:start-after: coarse:
|
:start-after: coarse:
|
||||||
:end-before: map_ram:
|
:end-before: map_ram:
|
||||||
:dedent:
|
:dedent:
|
||||||
|
|
Loading…
Reference in New Issue