diff --git a/doc/source/manual/conversion_examples.rst b/doc/source/manual/conversion_examples.rst index 38d0569c..4ab08af6 100644 --- a/doc/source/manual/conversion_examples.rst +++ b/doc/source/manual/conversion_examples.rst @@ -94,156 +94,34 @@ A hierarchical design The converter can handle designs with an arbitrarily deep hierarchy. For example, suppose we want to design an incrementer with Gray code output. -Using the designs from previous sections, we can proceed as follows:: +Using the designs from previous sections, we can proceed as follows: - def GrayInc(graycnt, enable, clock, reset, width): - - bincnt = Signal(intbv(0)[width:]) - - inc_1 = inc(bincnt, enable, clock, reset, n=2**width) - bin2gray_1 = bin2gray(B=bincnt, G=graycnt, width=width) - - return inc_1, bin2gray_1 +.. include-example:: gray_inc.py According to Gray code properties, only a single bit will change in consecutive values. However, as the ``bin2gray`` module is combinatorial, the output bits may have transient glitches, which may not be desirable. To solve this, let's create an additional level of hierarchy and add an output register to the design. (This will create an additional latency of a clock cycle, which may not -be acceptable, but we will ignore that here.) :: +be acceptable, but we will ignore that here.) - def GrayIncReg(graycnt, enable, clock, reset, width): +.. include-example:: gray_inc_reg.py - graycnt_comb = Signal(intbv(0)[width:]) - gray_inc_1 = GrayInc(graycnt_comb, enable, clock, reset, width) +We can convert this hierarchical design as follows: - @always(clock.posedge) - def reg_1(): - graycnt.next = graycnt_comb - - return gray_inc_1, reg_1 - -We can convert this hierarchical design as before:: - - width = 8 - graycnt = Signal(modbv(0)[width:]) - enable = Signal(bool()) - clock = Signal(bool()) - reset = ResetSignal(0, active=0, async=True) - - toVerilog(GrayIncReg, graycnt, enable, clock, reset, width) - toVHDL(GrayIncReg, graycnt, enable, clock, reset, width) - - -The Verilog output code looks as follows:: - - module GrayIncReg ( - graycnt, - enable, - clock, - reset - ); - - output [7:0] graycnt; - reg [7:0] graycnt; - input enable; - input clock; - input reset; - - reg [7:0] graycnt_comb; - reg [7:0] gray_inc_1_bincnt; - - always @(posedge clock, negedge reset) begin: GRAYINCREG_GRAY_INC_1_INC_1_INCLOGIC - if (reset == 0) begin - gray_inc_1_bincnt <= 0; - end - else begin - if (enable) begin - gray_inc_1_bincnt <= (gray_inc_1_bincnt + 1); - end - end - end - - always @(gray_inc_1_bincnt) begin: GRAYINCREG_GRAY_INC_1_BIN2GRAY_1_LOGIC - integer i; - reg [9-1:0] Bext; - Bext = 9'h0; - Bext = gray_inc_1_bincnt; - for (i=0; i<8; i=i+1) begin - graycnt_comb[i] = (Bext[(i + 1)] ^ Bext[i]); - end - end - - always @(posedge clock) begin: GRAYINCREG_REG_1 - graycnt <= graycnt_comb; - end - - endmodule - -The VHDL output code looks as follows:: - - library IEEE; - use IEEE.std_logic_1164.all; - use IEEE.numeric_std.all; - use work.pck_myhdl_08.all; - - entity GrayIncReg is - port ( - graycnt: out unsigned(7 downto 0); - enable: in std_logic; - clock: in std_logic; - reset: in std_logic - ); - end entity GrayIncReg; - - - architecture MyHDL of GrayIncReg is - - signal graycnt_comb: unsigned(7 downto 0); - signal gray_inc_1_bincnt: unsigned(7 downto 0); - - begin - - GRAYINCREG_GRAY_INC_1_INC_1_INCLOGIC: process (clock, reset) is - begin - if (reset = '0') then - gray_inc_1_bincnt <= (others => '0'); - elsif rising_edge(clock) then - if bool(enable) then - gray_inc_1_bincnt <= (gray_inc_1_bincnt + 1); - end if; - end if; - end process GRAYINCREG_GRAY_INC_1_INC_1_INCLOGIC; - - - GRAYINCREG_GRAY_INC_1_BIN2GRAY_1_LOGIC: process (gray_inc_1_bincnt) is - variable Bext: unsigned(8 downto 0); - begin - Bext := to_unsigned(0, 9); - Bext := resize(gray_inc_1_bincnt, 9); - for i in 0 to 8-1 loop - graycnt_comb(i) <= (Bext((i + 1)) xor Bext(i)); - end loop; - end process GRAYINCREG_GRAY_INC_1_BIN2GRAY_1_LOGIC; - - - GRAYINCREG_REG_1: process (clock) is - begin - if rising_edge(clock) then - graycnt <= graycnt_comb; - end if; - end process GRAYINCREG_REG_1; - - end architecture MyHDL; +.. include-example:: convert_gray_inc_reg.py +The Verilog output code looks as follows: +.. include-example:: gray_inc_reg.v +The VHDL output code looks as follows: +.. include-example:: gray_inc_reg.vhd Note that the output is a flat "net list of blocks", and that hierarchical signal names are generated as necessary. - .. _conv-usage-fsm: Optimizations for finite state machines diff --git a/example/manual/GrayIncReg.v b/example/manual/GrayIncReg.v deleted file mode 100644 index 2ad4b0f3..00000000 --- a/example/manual/GrayIncReg.v +++ /dev/null @@ -1,56 +0,0 @@ -// File: GrayIncReg.v -// Generated by MyHDL 0.8dev -// Date: Fri Dec 21 15:02:38 2012 - - -`timescale 1ns/10ps - -module GrayIncReg ( - graycnt, - enable, - clock, - reset -); - - -output [7:0] graycnt; -reg [7:0] graycnt; -input enable; -input clock; -input reset; - -reg [7:0] graycnt_comb; -reg [7:0] gray_inc_1_bincnt; - - - - - -always @(posedge clock, negedge reset) begin: GRAYINCREG_GRAY_INC_1_INC_1_INCLOGIC - if (reset == 0) begin - gray_inc_1_bincnt <= 0; - end - else begin - if (enable) begin - gray_inc_1_bincnt <= (gray_inc_1_bincnt + 1); - end - end -end - - -always @(gray_inc_1_bincnt) begin: GRAYINCREG_GRAY_INC_1_BIN2GRAY_1_LOGIC - integer i; - reg [9-1:0] Bext; - Bext = 9'h0; - Bext = gray_inc_1_bincnt; - for (i=0; i<8; i=i+1) begin - graycnt_comb[i] = (Bext[(i + 1)] ^ Bext[i]); - end -end - - -always @(posedge clock) begin: GRAYINCREG_REG_1 - graycnt <= graycnt_comb; -end - -endmodule diff --git a/example/manual/GrayIncReg.vhd b/example/manual/GrayIncReg.vhd deleted file mode 100644 index adc0dfd8..00000000 --- a/example/manual/GrayIncReg.vhd +++ /dev/null @@ -1,63 +0,0 @@ --- File: GrayIncReg.vhd --- Generated by MyHDL 0.8dev --- Date: Fri Dec 21 15:02:38 2012 - - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use std.textio.all; - -use work.pck_myhdl_08.all; - -entity GrayIncReg is - port ( - graycnt: out unsigned(7 downto 0); - enable: in std_logic; - clock: in std_logic; - reset: in std_logic - ); -end entity GrayIncReg; - - -architecture MyHDL of GrayIncReg is - -signal graycnt_comb: unsigned(7 downto 0); -signal gray_inc_1_bincnt: unsigned(7 downto 0); - -begin - - - - -GRAYINCREG_GRAY_INC_1_INC_1_INCLOGIC: process (clock, reset) is -begin - if (reset = '0') then - gray_inc_1_bincnt <= (others => '0'); - elsif rising_edge(clock) then - if bool(enable) then - gray_inc_1_bincnt <= (gray_inc_1_bincnt + 1); - end if; - end if; -end process GRAYINCREG_GRAY_INC_1_INC_1_INCLOGIC; - - -GRAYINCREG_GRAY_INC_1_BIN2GRAY_1_LOGIC: process (gray_inc_1_bincnt) is - variable Bext: unsigned(8 downto 0); -begin - Bext := to_unsigned(0, 9); - Bext := resize(gray_inc_1_bincnt, 9); - for i in 0 to 8-1 loop - graycnt_comb(i) <= (Bext((i + 1)) xor Bext(i)); - end loop; -end process GRAYINCREG_GRAY_INC_1_BIN2GRAY_1_LOGIC; - - -GRAYINCREG_REG_1: process (clock) is -begin - if rising_edge(clock) then - graycnt <= graycnt_comb; - end if; -end process GRAYINCREG_REG_1; - -end architecture MyHDL; diff --git a/example/manual/convert_gray_inc_reg.py b/example/manual/convert_gray_inc_reg.py new file mode 100644 index 00000000..8dae11cb --- /dev/null +++ b/example/manual/convert_gray_inc_reg.py @@ -0,0 +1,15 @@ +from myhdl import Signal, ResetSignal, modbv + +from gray_inc_reg import gray_inc_reg + +def convert_gray_inc_reg(hdl, width=8): + graycnt = Signal(modbv(0)[width:]) + enable = Signal(bool()) + clock = Signal(bool()) + reset = ResetSignal(0, active=0, async=True) + + inst = gray_inc_reg(graycnt, enable, clock, reset, width) + inst.convert(hdl) + +convert_gray_inc_reg(hdl='Verilog') +convert_gray_inc_reg(hdl='VHDL') diff --git a/example/manual/gray_inc.py b/example/manual/gray_inc.py new file mode 100644 index 00000000..09a4daef --- /dev/null +++ b/example/manual/gray_inc.py @@ -0,0 +1,15 @@ +from myhdl import block, Signal, modbv + +from bin2gray import bin2gray +from inc import inc + +@block +def gray_inc(graycnt, enable, clock, reset, width): + + bincnt = Signal(modbv(0)[width:]) + + inc_0 = inc(bincnt, enable, clock, reset) + bin2gray_0 = bin2gray(B=bincnt, G=graycnt) + + return inc_0, bin2gray_0 + diff --git a/example/manual/gray_inc_reg.py b/example/manual/gray_inc_reg.py new file mode 100644 index 00000000..0b6000c2 --- /dev/null +++ b/example/manual/gray_inc_reg.py @@ -0,0 +1,18 @@ +from myhdl import block, always_seq, Signal, modbv + +from gray_inc import gray_inc + +@block +def gray_inc_reg(graycnt, enable, clock, reset, width): + + graycnt_comb = Signal(modbv(0)[width:]) + + gray_inc_0 = gray_inc(graycnt_comb, enable, clock, reset, width) + gray_inc_0.name = "gray_inc_0" + + @always_seq(clock.posedge, reset=reset) + def reg_0(): + graycnt.next = graycnt_comb + + return gray_inc_0, reg_0 + diff --git a/example/manual/gray_inc_reg.v b/example/manual/gray_inc_reg.v new file mode 100644 index 00000000..938502e3 --- /dev/null +++ b/example/manual/gray_inc_reg.v @@ -0,0 +1,51 @@ +// File: gray_inc_reg.v +// Generated by MyHDL 1.0dev +// Date: Mon May 23 18:06:58 2016 + + +`timescale 1ns/10ps + +module gray_inc_reg ( + graycnt, + enable, + clock, + reset +); + + +output [7:0] graycnt; +reg [7:0] graycnt; +input enable; +input clock; +input reset; + +wire [7:0] graycnt_comb; +reg [7:0] gray_inc_0_bincnt; + + +always @(posedge clock, negedge reset) begin: GRAY_INC_REG_GRAY_INC_0_INC_0_SEQ + if (reset == 0) begin + gray_inc_0_bincnt <= 0; + end + else begin + if (enable) begin + gray_inc_0_bincnt <= (gray_inc_0_bincnt + 1); + end + end +end + + + +assign graycnt_comb = ((gray_inc_0_bincnt >>> 1) ^ gray_inc_0_bincnt); + + +always @(posedge clock, negedge reset) begin: GRAY_INC_REG_REG_0 + if (reset == 0) begin + graycnt <= 0; + end + else begin + graycnt <= graycnt_comb; + end +end + +endmodule diff --git a/example/manual/gray_inc_reg.vhd b/example/manual/gray_inc_reg.vhd new file mode 100644 index 00000000..20f0402f --- /dev/null +++ b/example/manual/gray_inc_reg.vhd @@ -0,0 +1,57 @@ +-- File: gray_inc_reg.vhd +-- Generated by MyHDL 1.0dev +-- Date: Mon May 23 18:06:58 2016 + + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use std.textio.all; + +use work.pck_myhdl_10.all; + +entity gray_inc_reg is + port ( + graycnt: out unsigned(7 downto 0); + enable: in std_logic; + clock: in std_logic; + reset: in std_logic + ); +end entity gray_inc_reg; + + +architecture MyHDL of gray_inc_reg is + + +signal graycnt_comb: unsigned(7 downto 0); +signal gray_inc_0_bincnt: unsigned(7 downto 0); + +begin + + + + +GRAY_INC_REG_GRAY_INC_0_INC_1_SEQ: process (clock, reset) is +begin + if (reset = '0') then + gray_inc_0_bincnt <= to_unsigned(0, 8); + elsif rising_edge(clock) then + if bool(enable) then + gray_inc_0_bincnt <= (gray_inc_0_bincnt + 1); + end if; + end if; +end process GRAY_INC_REG_GRAY_INC_0_INC_1_SEQ; + + +graycnt_comb <= (shift_right(gray_inc_0_bincnt, 1) xor gray_inc_0_bincnt); + +GRAY_INC_REG_REG_0: process (clock, reset) is +begin + if (reset = '0') then + graycnt <= to_unsigned(0, 8); + elsif rising_edge(clock) then + graycnt <= graycnt_comb; + end if; +end process GRAY_INC_REG_REG_0; + +end architecture MyHDL; diff --git a/example/manual/pck_myhdl_10.vhd b/example/manual/pck_myhdl_10.vhd index ba5b5765..cabbc7ce 100644 --- a/example/manual/pck_myhdl_10.vhd +++ b/example/manual/pck_myhdl_10.vhd @@ -1,6 +1,6 @@ -- File: pck_myhdl_10.vhd -- Generated by MyHDL 1.0dev --- Date: Mon May 23 16:09:27 2016 +-- Date: Mon May 23 18:06:58 2016 library ieee; diff --git a/example/manual/tb_gray_inc_reg.v b/example/manual/tb_gray_inc_reg.v new file mode 100644 index 00000000..3759d6be --- /dev/null +++ b/example/manual/tb_gray_inc_reg.v @@ -0,0 +1,26 @@ +module tb_gray_inc_reg; + +wire [7:0] graycnt; +reg enable; +reg clock; +reg reset; + +initial begin + $from_myhdl( + enable, + clock, + reset + ); + $to_myhdl( + graycnt + ); +end + +gray_inc_reg dut( + graycnt, + enable, + clock, + reset +); + +endmodule