A
akiriwas
Guest
I have a XESS XSA-50 board with a XC2S50 FPGA on it. I've done some
tutorials such as a counter that displays on the built in display.
The problem I'm having is that I found some VHDL code that controls a
stepper motor. I hooked it up and it worked great! So I know I have
my UCF constraint file correct. However, I prefer verilog as my
language of choice. I rewrote the code in verilog and tried to run
it, and instead of turning the stepper motor, the motor simple
agitated back and forth. The following is the code in VHDL:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
entity StepperMotorPorts is
Port ( StepDrive : out std_logic_vector(3 downto 0);
clock : in std_logic;
Direction : in std_logic;
StepEnable : in std_logic;
ProvideStaticHolding : in std_logic);
end StepperMotorPorts;
architecture StepDrive of StepperMotorPorts is
signal state : std_logic_vector(1 downto 0); -- simple state
machine, 4 states
signal StepCounter : std_logic_vector(31 downto 0); -- most motors
won't spin extrordinarially fast, so this slows the clock input way
down
constant StepLockOut : std_logic_vector(31 downto 0) :=
"00000000000000110000110101000000"; --rollover for the counter, to get
a non-binary delay time divider
signal InternalStepEnable : std_logic; -- used to capture a step
enable even when we are in the wait loop for the clock divider.
begin
process(clock)
begin
if clock'event and clock = '1' then
StepCounter <= StepCounter + "0000000000000000000000000000001";
--move the delay counter
if (StepEnable = '1') then
InternalStepEnable <= '1'; -- capture any requests for a step,
even while we are waiting...
end if;
if (StepCounter >= StepLockOut) then
StepCounter <= "00000000000000000000000000000000"; -- if we just
roll-ed over, then it's time to do something
if (ProvideStaticHolding = '1') then --should we leave coils in
energized state by defaul or not?
StepDrive <= "0000";
else
StepDrive <= "1111";
end if;
if (InternalStepEnable = '1') then -- are we supposed to step on
this clock?
InternalStepEnable <= StepEnable; -- InternalStepEnable togles
at the speed of the clock divider rollover, trailing the
-- external StepEnable by less than or equal to one
rollover.
-- Putting this inside the "if internal=1" makes us
wait until after move to turn off,
-- so we move at least once for each pulse of
external step enable line.
if (Direction = '1') then state <= state + "01"; end if; -- to
change the direction of a stepper motor, you energize
if (Direction = '0') then state <= state - "01"; end if; -- the
coils in the opposite pattern, so just run states backwards
-- this also allows a change of direction at
any arbitrary point
case state is
when "00" =>
StepDrive <= "1010"; -- these states follow proper pattern of
coil energizing for turning steppers
when "01" =>
StepDrive <= "1001";
when "10" =>
StepDrive <= "0101";
when "11" =>
StepDrive <= "0110";
when others =>
end case; --state
end if;
end if;
end if;
end process;
end StepDrive;
This is the code in Verilog:
// File translated with vhd2vl v 1.0
// VHDL to Verilog RTL translator
// Copyright (C) 2001 Vincenzo Liguori - Ocean Logic Pty Ltd -
http://www.ocean-logic.com
// vhd2vl comes with ABSOLUTELY NO WARRANTY
// This is free software, and you are welcome to redistribute it
// under certain conditions.
// See the license file license.txt included with the source for
details.
// Uncomment the following lines to use the declarations that are
// provided for instantiating Xilinx primitive components.
//library UNISIM;
//use UNISIM.VComponents.all;
module StepperMotorPorts(
StepDrive,
clock,
Direction,
StepEnable,
ProvideStaticHolding
);
output[3:0] StepDrive;
input clock;
input Direction;
input StepEnable;
input ProvideStaticHolding;
reg [3:0] StepDrive;
wire clock;
wire Direction;
wire StepEnable;
wire ProvideStaticHolding;
reg [1:0] state;
// simple state machine, 4 states
reg [31:0] StepCounter;
// most motors won't spin extrordinarially fast, so this slows the
clock input way down
parameter [31:0] StepLockOut = 32'b 00000000000000110000110101000000;
//rollover for the counter, to get a non-binary delay time divider
reg InternalStepEnable;
// used to capture a step enable even when we are in the wait loop for
the clock divider.
always @(posedge clock) begin
StepCounter <= StepCounter + 31'b 0000000000000000000000000000001;
//move the delay counter
if((StepEnable == 1'b 1)) begin
InternalStepEnable <= 1'b 1;
// capture any requests for a step, even while we are waiting...
end
if((StepCounter >= StepLockOut)) begin
StepCounter <= 32'b 00000000000000000000000000000000;
// if we just roll-ed over, then it's time to do something
if((ProvideStaticHolding == 1'b 1)) begin
//should we leave coils in energized state by defaul or not?
StepDrive <= 4'b 0000;
end
else begin
StepDrive <= 4'b 1111;
end
if((InternalStepEnable == 1'b 1)) begin
// are we supposed to step on this clock?
InternalStepEnable <= StepEnable;
// InternalStepEnable togles at the speed of the clock divider
rollover, trailing the
// external StepEnable by less than or equal to one rollover.
// Putting this inside the "if internal=1" makes us wait until
after move to turn off,
// so we move at least once for each pulse of external step
enable line.
if((Direction == 1'b 1)) begin
state <= state + 2'b 01;
end
// to change the direction of a stepper motor, you energize
if((Direction == 1'b 0)) begin
state <= state - 2'b 01;
end
// the coils in the opposite pattern, so just run states
backwards
// this also allows a change of direction at any arbitrary
point
case(state)
2'b 00 : begin
StepDrive <= 4'b 1010;
// these states follow proper pattern of coil energizing for
turning steppers
end
2'b 01 : begin
StepDrive <= 4'b 1001;
end
2'b 10 : begin
StepDrive <= 4'b 0101;
end
2'b 11 : begin
StepDrive <= 4'b 0110;
end
default : begin
end
endcase
//state
end
end
end
endmodule
Does anyone have any ideas as to what I'm doing wrong with the verilog
version that it isn't running properly?
tutorials such as a counter that displays on the built in display.
The problem I'm having is that I found some VHDL code that controls a
stepper motor. I hooked it up and it worked great! So I know I have
my UCF constraint file correct. However, I prefer verilog as my
language of choice. I rewrote the code in verilog and tried to run
it, and instead of turning the stepper motor, the motor simple
agitated back and forth. The following is the code in VHDL:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
entity StepperMotorPorts is
Port ( StepDrive : out std_logic_vector(3 downto 0);
clock : in std_logic;
Direction : in std_logic;
StepEnable : in std_logic;
ProvideStaticHolding : in std_logic);
end StepperMotorPorts;
architecture StepDrive of StepperMotorPorts is
signal state : std_logic_vector(1 downto 0); -- simple state
machine, 4 states
signal StepCounter : std_logic_vector(31 downto 0); -- most motors
won't spin extrordinarially fast, so this slows the clock input way
down
constant StepLockOut : std_logic_vector(31 downto 0) :=
"00000000000000110000110101000000"; --rollover for the counter, to get
a non-binary delay time divider
signal InternalStepEnable : std_logic; -- used to capture a step
enable even when we are in the wait loop for the clock divider.
begin
process(clock)
begin
if clock'event and clock = '1' then
StepCounter <= StepCounter + "0000000000000000000000000000001";
--move the delay counter
if (StepEnable = '1') then
InternalStepEnable <= '1'; -- capture any requests for a step,
even while we are waiting...
end if;
if (StepCounter >= StepLockOut) then
StepCounter <= "00000000000000000000000000000000"; -- if we just
roll-ed over, then it's time to do something
if (ProvideStaticHolding = '1') then --should we leave coils in
energized state by defaul or not?
StepDrive <= "0000";
else
StepDrive <= "1111";
end if;
if (InternalStepEnable = '1') then -- are we supposed to step on
this clock?
InternalStepEnable <= StepEnable; -- InternalStepEnable togles
at the speed of the clock divider rollover, trailing the
-- external StepEnable by less than or equal to one
rollover.
-- Putting this inside the "if internal=1" makes us
wait until after move to turn off,
-- so we move at least once for each pulse of
external step enable line.
if (Direction = '1') then state <= state + "01"; end if; -- to
change the direction of a stepper motor, you energize
if (Direction = '0') then state <= state - "01"; end if; -- the
coils in the opposite pattern, so just run states backwards
-- this also allows a change of direction at
any arbitrary point
case state is
when "00" =>
StepDrive <= "1010"; -- these states follow proper pattern of
coil energizing for turning steppers
when "01" =>
StepDrive <= "1001";
when "10" =>
StepDrive <= "0101";
when "11" =>
StepDrive <= "0110";
when others =>
end case; --state
end if;
end if;
end if;
end process;
end StepDrive;
This is the code in Verilog:
// File translated with vhd2vl v 1.0
// VHDL to Verilog RTL translator
// Copyright (C) 2001 Vincenzo Liguori - Ocean Logic Pty Ltd -
http://www.ocean-logic.com
// vhd2vl comes with ABSOLUTELY NO WARRANTY
// This is free software, and you are welcome to redistribute it
// under certain conditions.
// See the license file license.txt included with the source for
details.
// Uncomment the following lines to use the declarations that are
// provided for instantiating Xilinx primitive components.
//library UNISIM;
//use UNISIM.VComponents.all;
module StepperMotorPorts(
StepDrive,
clock,
Direction,
StepEnable,
ProvideStaticHolding
);
output[3:0] StepDrive;
input clock;
input Direction;
input StepEnable;
input ProvideStaticHolding;
reg [3:0] StepDrive;
wire clock;
wire Direction;
wire StepEnable;
wire ProvideStaticHolding;
reg [1:0] state;
// simple state machine, 4 states
reg [31:0] StepCounter;
// most motors won't spin extrordinarially fast, so this slows the
clock input way down
parameter [31:0] StepLockOut = 32'b 00000000000000110000110101000000;
//rollover for the counter, to get a non-binary delay time divider
reg InternalStepEnable;
// used to capture a step enable even when we are in the wait loop for
the clock divider.
always @(posedge clock) begin
StepCounter <= StepCounter + 31'b 0000000000000000000000000000001;
//move the delay counter
if((StepEnable == 1'b 1)) begin
InternalStepEnable <= 1'b 1;
// capture any requests for a step, even while we are waiting...
end
if((StepCounter >= StepLockOut)) begin
StepCounter <= 32'b 00000000000000000000000000000000;
// if we just roll-ed over, then it's time to do something
if((ProvideStaticHolding == 1'b 1)) begin
//should we leave coils in energized state by defaul or not?
StepDrive <= 4'b 0000;
end
else begin
StepDrive <= 4'b 1111;
end
if((InternalStepEnable == 1'b 1)) begin
// are we supposed to step on this clock?
InternalStepEnable <= StepEnable;
// InternalStepEnable togles at the speed of the clock divider
rollover, trailing the
// external StepEnable by less than or equal to one rollover.
// Putting this inside the "if internal=1" makes us wait until
after move to turn off,
// so we move at least once for each pulse of external step
enable line.
if((Direction == 1'b 1)) begin
state <= state + 2'b 01;
end
// to change the direction of a stepper motor, you energize
if((Direction == 1'b 0)) begin
state <= state - 2'b 01;
end
// the coils in the opposite pattern, so just run states
backwards
// this also allows a change of direction at any arbitrary
point
case(state)
2'b 00 : begin
StepDrive <= 4'b 1010;
// these states follow proper pattern of coil energizing for
turning steppers
end
2'b 01 : begin
StepDrive <= 4'b 1001;
end
2'b 10 : begin
StepDrive <= 4'b 0101;
end
2'b 11 : begin
StepDrive <= 4'b 0110;
end
default : begin
end
endcase
//state
end
end
end
endmodule
Does anyone have any ideas as to what I'm doing wrong with the verilog
version that it isn't running properly?