Altera_Forum
Honored Contributor
13 years agoSimple SPI shift register, mismatch between simulation and real behavior
This is a shot in the dark, but I have what should be an essentially very simple shift register design, that should accept a byte from the SPI peripheral of a microcontroller.
Ideally the device should work like this:- The microcontroller selects the register by bringing cs_power low
- The microcontroller clocks out 8 bits. Data is asserted on spi_mosi on the falling edges of the clock, and data is read into the register on the rising edges
- The microcontroller deselects the register by bringing cs_power high
- On the deselct, the 8 data bits transmitted are latched into latch_reg. Bits are routed individually to other parts of the design for various functions (not shown here) - two of the bits, power_hv507 and ref_select are connected to bits 1 and 6 of that latch respectively. To test for proper operation of the register, I've connected these signals to pins on my MAXII CPLD, and am watching them on my oscilloscope.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity effector_module is
port (
spi_sclk : in std_logic := '0';
spi_mosi : in std_logic := '0';
cs_hv507 : in std_logic := '1';
cs_impedance : in std_logic := '1';
cs_cart : in std_logic := '1';
cs_vctl : in std_logic := '1';
cs_feedback : in std_logic := '1';
cs_hv507_clk : in std_logic := '1';
cs_power : in std_logic := '1';
hv507_fault : in std_logic := '0'; -- new 14
err : in std_logic := '0'; -- new 12
fault_cart : in std_logic := '0'; -- new 2
timer : inout std_logic := '0';
hv_suppress : inout std_logic := '0'; -- new 10
power_cart : inout std_logic := '0'; -- new 3
cart_present : inout std_logic := '0'; -- new 4
blank : inout std_logic := '0'; -- new 5
power_hv507 : out std_logic := '0'; -- new 13
ref_select : out std_logic := '0'; -- new 8
not_hv_shdn : out std_logic := '0'; -- new 9
bleed : out std_logic := '0'; -- new 11
cart_miso_dir : out std_logic := '0'; -- new 1
pol : out std_logic := '0'; -- new 6
sck_hv507 : out std_logic := '0'; -- new 7
spi_miso : out std_logic := 'Z';
tapsout : out std_logic_vector (7 downto 0)
);
end effector_module;
library ieee;
use ieee.std_logic_1164.all;
entity basic_shift_register is
generic
(
NUM_STAGES : natural := 256
);
port
(
clk : in std_logic;
enable : in std_logic;
sr_in : in std_logic;
sr_out : out std_logic;
taps : inout std_logic_vector ((NUM_STAGES-1) downto 0)
);
end entity;
-- Shift register with active low enable
architecture rtl of basic_shift_register is
-- Build an array type for the shift register
-- Declare the shift register signal
begin
process (clk, enable, taps)
begin
if (enable = '1') then
taps((NUM_STAGES-1) downto 0) <= taps((NUM_STAGES-1) downto 0);
elsif (rising_edge(clk)) then
-- Shift data by one stage; data from last stage is lost
taps((NUM_STAGES-1) downto 1) <= taps((NUM_STAGES-2) downto 0);
-- Load new data into the first stage
taps(0) <= sr_in;
end if;
end process;
-- Capture the data from the last stage, before it is lost
sr_out <= taps(NUM_STAGES-1);
end rtl;
architecture rtl of effector_module is
signal delta : std_logic;
signal clear_sticky : std_logic;
signal dc_mode : std_logic;
signal pwr : std_logic_vector(7 downto 0);
signal latch_reg : std_logic_vector(7 downto 0);
begin
power_hv507 <= pwr(1);
ref_select <= pwr(6);
power_sr : entity work.basic_shift_register(rtl)
generic map( NUM_STAGES => 8)
port map(
clk => spi_sclk,
enable => cs_power,
sr_in => spi_mosi,
taps => pwr
);
process (cs_power, pwr)
begin
if rising_edge(cs_power) then
latch_reg <= pwr;
end if;
end process;
end rtl;