📄 stepgen.vhd
字号:
-- Notes-- With the default generic values, 'stepgen_core'-- uses 93 FFs and 121 LUTs. Increasing 'timer_size'-- adds about 3.3 FFs and 3 LUTs per bit. Decreasing-- 'timer_size' from 12 to 11 _adds_ about 40 LUTs.-- Increasing 'acc_size' costs one FF and one LUT per-- bit, while increasing 'rate_sze' costs 1 LUT per bit.-- Changing 'pos_size' has no effect.-- These numbers apply to the core only. Since the rates-- and time values need to be written to registers by the-- PC, those registers will use one FF per bit. Likewise,-- the position feedback will use LUTs to drive the bus.library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;use IEEE.STD_LOGIC_SIGNED.ALL;package stepgen_pkg iscomponent stepgen_core is generic ( -- size of accumulator acc_size : integer := 48; -- size of position feedback pos_size : integer := 32; -- size (resolution) of rate value rate_size : integer := 24; -- size of length, hold, and setup timers timer_size : integer := 12 ); port ( clock : in std_logic; enable : in std_logic; position : buffer std_logic_vector ( pos_size-1 downto 0); rate : in std_logic_vector ( rate_size-1 downto 0 ); steplen : in std_logic_vector ( timer_size-1 downto 0 ); holdtime : in std_logic_vector ( timer_size-1 downto 0 ); setuptime : in std_logic_vector ( timer_size-1 downto 0 ); stepout : buffer std_logic; dirout : buffer std_logic; stepup : buffer std_logic; stepdown : buffer std_logic; phasea : buffer std_logic; phaseb : buffer std_logic );end component stepgen_core;component stepgen is port ( clock : in std_logic; enable : in std_logic; ibus : in std_logic_vector (31 downto 0); obus : out std_logic_vector (31 downto 0); sel : in std_logic; write : in std_logic; read : in std_logic; addr : in std_logic_vector (1 downto 0 ); out0 : out std_logic; out1 : out std_logic );end component stepgen;end stepgen_pkg;library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;use IEEE.STD_LOGIC_SIGNED.ALL;use work.oneshot_pkg.all;-- this is the core of a step generator.-- it is completely configurable, and contains no registers-- all of its control signals are provided through ports-- see 'stepgen' below for a instance of a stepgen-- with a bus interface and control registersentity stepgen_core is generic ( acc_size : integer := 48; pos_size : integer := 32; rate_size : integer := 24; timer_size : integer := 12 ); port ( clock : in std_logic; enable : in std_logic; position : buffer std_logic_vector ( pos_size-1 downto 0); rate : in std_logic_vector ( rate_size-1 downto 0 ); steplen : in std_logic_vector ( timer_size-1 downto 0 ); holdtime : in std_logic_vector ( timer_size-1 downto 0 ); setuptime : in std_logic_vector ( timer_size-1 downto 0 ); stepout : buffer std_logic := '0'; dirout : buffer std_logic := '0'; stepup : buffer std_logic := '0'; stepdown : buffer std_logic := '0'; phasea : buffer std_logic := '0'; phaseb : buffer std_logic := '0' );end stepgen_core;architecture behavioral of stepgen_core is constant pickoff_bit: integer := rate_size + 1; signal accum: std_logic_vector ( acc_size-1 downto 0 ) := (others => '0'); alias pickoff: std_logic is accum(pickoff_bit); signal nextaccum: std_logic_vector ( acc_size-1 downto 0 ); alias nextpickoff: std_logic is nextaccum(pickoff_bit); alias dirreq: std_logic is rate(rate_size-1); signal ddshold: std_logic; signal stepreq : std_logic := '0'; signal dirhold: std_logic; signal dirsetup: std_logic; signal starthold: std_logic; signal dirchange: std_logic;begin StepDDS: process (clock, ddshold, rate, accum, nextaccum, enable) begin -- combinatorial stuff nextaccum <= signed(accum) + signed(rate); position <= accum(acc_size-1 downto acc_size-pos_size); -- clocked stuff if clock'event and clock = '1' then if ddshold = '0' and enable = '1' then accum <= nextaccum; stepreq <= pickoff xor nextpickoff; else stepreq <= '0'; end if; end if; end process; Timing: process (clock, stepreq, stepout, rate, dirreq, dirout, dirchange, dirsetup, dirhold) begin -- combinatorial starthold <= stepreq or stepout; dirchange <= dirreq xor dirout; ddshold <= dirchange or dirsetup; -- clocked if clock'event and clock = '1' then if dirhold = '0' and stepreq = '0' then dirout <= dirreq; end if; end if; end process; Output: process (clock, stepreq, stepout, dirout, phasea, phaseb) begin -- conbinatorial stepup <= stepout and not dirout; stepdown <= stepout and dirout; -- clocked if clock'event and clock = '1' then if stepreq = '1' then phasea <= phaseb xor dirout; phaseb <= phasea xor not dirout; end if; end if; end process; StepTimer: oneshot generic map ( timer_size ) port map ( input => stepreq, output => stepout, clock => clock, duration => steplen ); HoldTimer: oneshot generic map ( timer_size ) port map ( input => starthold, output => dirhold, clock => clock, duration => holdtime ); SetupTimer: oneshot generic map ( timer_size ) port map ( input => dirchange, output => dirsetup, clock => clock, duration => setuptime );end behavioral;library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;use IEEE.STD_LOGIC_SIGNED.ALL;use work.stepgen_pkg.all;-- this entity provides a step generator core along with-- a bus interface and registers to allow the PC to control it-- write registers:-- 00: 00-23 = rate (24 bits)-- 01: 00-13 = step length (14 bits)-- 16-17 = mode (00-off, 01-step/dir, 02-up/down, 03-quadrature)-- 18 = enable (0-off, 1-on)-- 02: 00-13 = direction hold time (14 bits)-- 16-29 = direction setup time (14 bits)-- read registers:-- 00: 00-07 = position (fractional steps)-- 08-31 = position (whole steps)entity stepgen is port ( clock : in std_logic; enable : in std_logic; ibus : in std_logic_vector (31 downto 0); obus : out std_logic_vector (31 downto 0); sel : in std_logic; write : in std_logic; read : in std_logic; addr : in std_logic_vector (1 downto 0 ); out0 : out std_logic; out1 : out std_logic );end stepgen;architecture behavioral of stepgen is signal wr_reg0: std_logic_vector ( 31 downto 0 ) := (others => '0'); signal wr_reg1: std_logic_vector ( 31 downto 0 ) := (others => '0'); signal wr_reg2: std_logic_vector ( 31 downto 0 ) := (others => '0'); signal rd_reg0: std_logic_vector ( 31 downto 0 ); signal wr0: std_logic; signal wr1: std_logic; signal wr2: std_logic; signal rd0: std_logic; signal stepout : std_logic; signal dirout : std_logic; signal stepup : std_logic; signal stepdown : std_logic; signal phasea : std_logic; signal phaseb : std_logic; signal local_enable : std_logic;begin BusInterface: process (clock, sel, read, write, addr, ibus, rd_reg0, enable, wr_reg1) begin -- combinatorial stuff -- decoding wr0 <= sel and write and not addr(1) and not addr(0); wr1 <= sel and write and not addr(1) and addr(0); wr2 <= sel and write and addr(1) and not addr(0); rd0 <= sel and read and not addr(1) and not addr(0); -- reading obus <= (others => 'Z'); if rd0 = '1' then obus <= rd_reg0; end if; -- enable = global enable and enable bit in mode register local_enable <= enable and wr_reg1(18); -- clocked stuff if clock'event and clock = '1' then -- writing if wr0 = '1' then wr_reg0 <= ibus; end if; if wr1 = '1' then wr_reg1 <= ibus; end if; if wr2 = '1' then wr_reg2 <= ibus; end if; end if; end process; ModeLogic: process (stepout, dirout, stepup, stepdown, phasea, phaseb, wr_reg1) begin -- combinatorial stuff case wr_reg1(17 downto 16) is when "00" => out0 <= '0' ; out1 <= '0'; when "01" => out0 <= stepout ; out1 <= dirout; when "10" => out0 <= stepup ; out1 <= stepdown; when "11" => out0 <= phasea ; out1 <= phaseb; when others => out0 <= '0' ; out1 <= '0'; end case; end process; Core: stepgen_core generic map ( acc_size => 48, pos_size => 32, rate_size => 24, timer_size => 14 ) port map ( stepout => stepout, dirout => dirout, stepup => stepup, stepdown => stepdown, phasea => phasea, phaseb => phaseb, rate => wr_reg0(23 downto 0), steplen => wr_reg1(13 downto 0), holdtime => wr_reg2(13 downto 0), setuptime => wr_reg2(29 downto 16), position => rd_reg0(31 downto 0), enable => local_enable, clock => clock );end behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -