mirror of
https://github.com/myhdl/myhdl.git
synced 2024-12-14 07:44:38 +08:00
manual update
This commit is contained in:
parent
5e1045ef9b
commit
62675e6a80
@ -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
|
||||
|
@ -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
|
@ -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;
|
15
example/manual/convert_gray_inc_reg.py
Normal file
15
example/manual/convert_gray_inc_reg.py
Normal file
@ -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')
|
15
example/manual/gray_inc.py
Normal file
15
example/manual/gray_inc.py
Normal file
@ -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
|
||||
|
18
example/manual/gray_inc_reg.py
Normal file
18
example/manual/gray_inc_reg.py
Normal file
@ -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
|
||||
|
51
example/manual/gray_inc_reg.v
Normal file
51
example/manual/gray_inc_reg.v
Normal file
@ -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
|
57
example/manual/gray_inc_reg.vhd
Normal file
57
example/manual/gray_inc_reg.vhd
Normal file
@ -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;
|
@ -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;
|
||||
|
26
example/manual/tb_gray_inc_reg.v
Normal file
26
example/manual/tb_gray_inc_reg.v
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user