Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY DAC_OUT IS
PORT
(
CLK : IN STD_LOGIC;
RESET : IN STD_LOGIC;
data : IN STD_LOGIC_VECTOR(15 downto 0);
dav : IN STD_LOGIC;
SCK : OUT STD_LOGIC;
nCS : OUT STD_LOGIC;
MOSI : OUT STD_LOGIC
);
END DAC_OUT;
ARCHITECTURE rtl OF DAC_OUT IS
SIGNAL sr : STD_LOGIC_VECTOR(15 downto 0);
SIGNAL bitcnt : INTEGER RANGE 0 TO 15;
SIGNAL clkdiv : INTEGER RANGE 0 TO 40;
SIGNAL DACCLKi : STD_LOGIC;
BEGIN
PROCESS(clk, reset)
BEGIN
IF reset = '1' THEN
bitcnt <= 0;
nCS <= '1';
DACCLKi <= '0';
clkdiv <= 0;
ELSIF rising_edge(clk) THEN
IF clkdiv < 38 THEN
clkdiv <= clkdiv + 1;
ELSE
clkdiv <= 0;
IF dav = '1' AND bitcnt = 0 THEN
DACCLKi <= '1';
sr <= data;
nCS <= '0';
bitcnt <= 15;
ELSIF bitcnt > 0 THEN
DACCLKi <= NOT DACCLKi;
IF DACCLKi = '0' THEN -- this is a rising edge
bitcnt <= bitcnt - 1;
IF bitcnt > 0 THEN
sr <= sr(14 downto 0) & "0";
ELSE
nCS <= '1';
END IF;
END IF;
ELSE
DACCLKi <= '0';
END IF;
END IF;
END IF;
END PROCESS;
SCK <= DACCLKi;
MOSI <= sr(15);
END rtl;
Yeah, I stand corrected. I noticed that clk_38 and went "huh?".
A similar SPI interface, slightly tidied up.
Code:LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY DAC_OUT IS PORT ( CLK : IN STD_LOGIC; RESET : IN STD_LOGIC; data : IN STD_LOGIC_VECTOR(15 downto 0); dav : IN STD_LOGIC; SCK : OUT STD_LOGIC; nCS : OUT STD_LOGIC; MOSI : OUT STD_LOGIC ); END DAC_OUT; ARCHITECTURE rtl OF DAC_OUT IS SIGNAL sr : STD_LOGIC_VECTOR(15 downto 0); SIGNAL bitcnt : INTEGER RANGE 0 TO 15; SIGNAL clkdiv : INTEGER RANGE 0 TO 40; SIGNAL DACCLKi : STD_LOGIC; BEGIN PROCESS(clk, reset) BEGIN IF reset = '1' THEN bitcnt <= 0; nCS <= '1'; DACCLKi <= '0'; clkdiv <= 0; ELSIF rising_edge(clk) THEN IF clkdiv < 38 THEN clkdiv <= clkdiv + 1; ELSE clkdiv <= 0; IF dav = '1' AND bitcnt = 0 THEN DACCLKi <= '1'; sr <= data; nCS <= '0'; bitcnt <= 15; ELSIF bitcnt > 0 THEN DACCLKi <= NOT DACCLKi; IF DACCLKi = '0' THEN -- this is a rising edge bitcnt <= bitcnt - 1; IF bitcnt > 0 THEN sr <= sr(14 downto 0) & "0"; ELSE nCS <= '1'; END IF; END IF; ELSE DACCLKi <= '0'; END IF; END IF; END IF; END PROCESS; SCK <= DACCLKi; MOSI <= sr(15); END rtl;
It seem like reviewing the code was necessary to discuss synchronous design principles and coding style.That is why I didn't wanted to paste code as I am interested on principal and coding style more than have a code to do the SPI.
On the other hand, the bare SPI function can be probably implemented on 1/3 or 1/4 the number of code lines. There's also some garbage like an unsused shift left function. It will be ignored in synthesis and most likely doesn't cost resources but affects code readablity. There are also some inconsistencies, you have a word length parameter, but the internal bit count is fixed to eight.
Personally, I tend to put a trivial SPI interface like this in a single process.
Not all all. Coding style is however a subjective category and I don't claim a solution that fits everyone's needs.Yes I was surprised when I so your code and I have commend it, but it will be very hard to scale from you code to include more functionality to it, I am sure you could end up adding more control signals a condition stages but I am sure it will get very messy to visualize and debug, do you think?
Regarding debugging. I don't know if you finally managed to make your code work. But from the previous posts, I got the impression that it's far from easy to debug.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity spi_forum is
generic(N: integer := 8);
port(
clk, reset, W: in std_logic;
data: in std_logic_vector(N-1 downto 0);
ready_out: out std_logic;
clock_38: out std_logic;
serial_out: out std_logic
);
end spi_forum;
architecture Behavioral of spi_forum is
--signals
signal counter_8clk : std_logic_vector(3 downto 0);
signal counter_8clk_tick : std_logic:='0';
signal counter_reset : std_logic:='0';
--clock_divided
signal clkCount: std_logic_vector (5 downto 0);
signal OneUSClk: std_logic:='0';
signal sclk_out_tick1: std_logic:='0';
signal sclk_out_tick2: std_logic:='0';
signal sclk_out_tick3: std_logic:='0';
signal sclk_out_tick_p: std_logic:='0';
signal sclk_out_tick_p2: std_logic:='0';
signal idle_load: std_logic:='0';
-- shift register
signal r_reg: std_logic_vector(N-1 downto 0);
signal r_next: std_logic_vector(N-1 downto 0);
signal ctrl: std_logic_vector(1 downto 0);
-- ready
signal ready: std_logic:='0';
--**************************************************************************
-- STATE MACHINE SIGNAL DECLARATION:
type StateType is (
idle,
send_data
);
signal CurrentState, NextState : StateType;
--**************************************************************************
begin
COMB: process(CurrentState ,W , counter_8clk,sclk_out_tick3) --leave_signal
begin
case CurrentState is
when idle =>
if (W = '1') then
NextState <= send_data;
else
NextState <= idle;
end if;
when send_data =>
if ((sclk_out_tick3 = '1') and (counter_8clk = "1000" ))then
NextState <= idle;
else
NextState <= send_data;
end if;
end case;
end process COMB;
SEQ: process(reset, clk)
begin
if(reset = '1') then
CurrentState <= idle;
elsif (clk'event and clk = '1') then
CurrentState <= NextState;
end if;
end process SEQ;
with CurrentState select
counter_reset <= '1' when idle,
'0' when send_data,
'1' when Others;
with CurrentState select
ctrl <= "11" when idle,
"10" when send_data,
"11" when others;
with CurrentState select
ready <= '1' when idle,
'0' when send_data,
'0' when others;
with CurrentState select
idle_load <= '1' when idle,
'0' when others;
ready_out <= ready;
--**************************************************************************
-- 4 bit counter - 8 times count
--**************************************************************************
process(reset, clk, counter_reset,sclk_out_tick_p,counter_8clk)
begin
if((reset = '1') or (counter_reset = '1')) then
counter_8clk <= (others=>'0');
counter_8clk_tick <= '0';
elsif (clk = '1' and clk'event) then
if (sclk_out_tick_p = '1') then
if (counter_8clk = "1000") then -- Terminal Count value
counter_8clk <= (others=>'0');
counter_8clk_tick <= '1';
else
counter_8clk <= counter_8clk + 1;
counter_8clk_tick <= '0';
end if;
end if;
end if;
end process;
--**************************************************************************
-- 6 bit counter - 38 times count
--**************************************************************************
process (clk,reset,clkCount,counter_reset)
begin
if ((reset = '1') or (counter_reset = '1')) then
clkCount <= "100110";
sclk_out_tick1 <= '0';
OneUSClk <= '0';
elsif (clk = '1' and clk'event) then
if(clkCount = "100110") then -- 38
clkCount <= "000000";
oneUSClk <= not oneUSClk;
sclk_out_tick1 <= '1';
elsif (clkCount = "100100") then --36
sclk_out_tick2 <= '1';
clkCount <= clkCount + 1;
elsif (clkCount = "100101") then -- 37
sclk_out_tick3 <= '1';
sclk_out_tick2 <= '0';
clkCount <= clkCount + 1;
else
clkCount <= clkCount + 1;
sclk_out_tick1 <= '0';
sclk_out_tick2 <= '0';
sclk_out_tick3 <= '0';
end if;
end if;
end process;
clock_38 <= oneUSClk;
sclk_out_tick_p <= '1' when sclk_out_tick1 = '1' and oneUSClk = '1' else '0';
sclk_out_tick_p2 <= '1' when sclk_out_tick2 = '1' and oneUSClk = '0' else '0';
--**************************************************************************
-- shift register
--**************************************************************************
-- register
process(clk,reset,sclk_out_tick1,sclk_out_tick_p,idle_load,data)
begin
if (reset='1') then
r_reg <= data;
elsif (clk'event and clk='1') then
if ((sclk_out_tick_p2 = '1' and counter_8clk >= "000001" ) or (idle_load = '1')) then
r_reg <= r_next;
end if;
end if;
end process;
with ctrl select
r_next <=
r_reg when "00", --no op
r_reg(N-2 downto 0) & data(0) when "01", --shift left;
data(N-1) & r_reg(N-1 downto 1) when "10", --shift right;
data when others; -- load
serial_out <= r_reg(0);
end Behavioral;
process (clk,reset,clkCount,counter_reset)
begin
if ((reset = '1') or (counter_reset = '1')) then
clkCount <= "100110";
sclk_out_tick1 <= '0';
OneUSClk <= '0';
elsif (clk = '1' and clk'event) then
if(clkCount = "100110") then -- 38
clkCount <= "000000";
oneUSClk <= not oneUSClk;
sclk_out_tick3 <= '0';
sclk_out_tick1 <= '1';
elsif (clkCount = "100100") then --36
sclk_out_tick2 <= '1';
clkCount <= clkCount + 1;
sclk_out_tick3 <= '0';
elsif (clkCount = "100101") then -- 37
sclk_out_tick3 <= '1';
sclk_out_tick2 <= '0';
clkCount <= clkCount + 1;
else
clkCount <= clkCount + 1;
sclk_out_tick1 <= '0';
sclk_out_tick2 <= '0';
sclk_out_tick3 <= '0';
end if;
end if;
end process;
clock_38 <= oneUSClk;
sclk_out_tick_p <= '1' when sclk_out_tick1 = '1' and oneUSClk = '1' else '0';
sclk_out_tick_p2 <= '1' when sclk_out_tick2 = '1' and oneUSClk = '0' else '0';
sclk_out_tick_p3 <= '1' when sclk_out_tick3 = '1' and oneUSClk = '0' else '0';
upcnt8_module : upcnt8
port map (
clk => clk ,
clr => not cnt_reset ,
cnt_en => sclk_out_tick_p_sync_ad_cnt,
qout => counter_8clk);
Looks like a step backwards. What's cnt_reset exactly doing?cnt_reset <= '1' when (counter_8clk = "1000") or (reset ='1') or (counter_reset = '1') else '0';
Looks like a step backwards. .
What's cnt_reset exactly doing?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_arith.all;
entity upcnt8 is
port(
cnt_en : in STD_LOGIC; -- Count enable -- Load line enable
clr : in STD_LOGIC; -- Active low clear
clk : in STD_LOGIC; -- Clock
qout : inout STD_LOGIC_VECTOR (3 downto 0)
);
end upcnt8;
architecture Behavioral of upcnt8 is
constant RESET_ACTIVE : std_logic := '0';
signal q_int : UNSIGNED (3 downto 0);
begin
process(clk, clr)
begin
-- Clear output register
if (clr = RESET_ACTIVE) then
q_int <= (others => '0');
-- On falling edge of clock count
elsif (clk'event) and clk = '1' then
if cnt_en = '1' then
q_int <= q_int + 1;
end if;
end if;
end process;
qout <= STD_LOGIC_VECTOR(q_int);
end Behavioral;
upcnt8_module : upcnt8
port map (
clk => clk ,
clr => not cnt_reset ,
cnt_en => sclk_out_tick_p_sync_ad_cnt,
qout => counter_8clk);
Are you pulling the design wide initial reset into the clock edge sensitive code or are you applying asynchronous reset in regular conter operation? Both won't be a good idea.
if (counter_8clk = "1000") then -- Terminal Count value
counter_8clk <= (others=>'0');
counter_8clk_tick <= '1';
else ...............
You are doing not the same. Previously, your counter has been counting 0,1,2 ... 7, 8, 0 ,1 now it's 0,1,2 ... 7, 0 ,1no I am doing all exactly the same as post #47, but all in multi-blocks
You are doing not the same. Previously, your counter has been counting 0,1,2 ... 7, 8, 0 ,1 now it's 0,1,2 ... 7, 0 ,1
That's a result of the asynchronous reset on counter_8clk = "1000".
But the full truth is, you had already asynchronous resets by signal counter_reset (on CurrentState = idle) in your previous code. That's also bad coding style that I wasn't aware of before.
There are different reasons why asynchronous reset of registers should be avoided, to mention the worst one, logic glitches can cause an unwanted reset when multiple inputs to the reset condition change at the same time. It's even possible that only some register bits are reset and others keep their previous value. .
In so far my valuation of the code in post #35 has to be narrowed.
there is going to be one type of reset one way or another one, do you suggest loading process? but bare in mind that reset is kind of loading, right?
The code had been certainly improved. In so far it deserves a good comment. But it's not fully synchronous as it should be.Sorry what do you mean? you have to take off the good comments?
The code had been certainly improved. In so far it deserves a good comment. But it's not fully synchronous as it should be.
- Sclk can be reset to 0 while in idle and then set it to 1 when you're making the transition out of idle; set it back to 0 halfway through the 37..0 counting
Kevin Jennings
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity spi_forum2 is
generic(N: integer := 8);
port(
clk, reset, W: in std_logic;
data: in std_logic_vector(N-1 downto 0);
ready_out: out std_logic;
clock_38: out std_logic;
serial_out: out std_logic
);
end spi_forum2;
architecture Behavioral of spi_forum2 is
--signals
signal counter_8clk : std_logic_vector(3 downto 0);
signal counter_8clk_tick : std_logic:='0';
signal counter_reset : std_logic:='0';
--clock_divided
signal clkCount: std_logic_vector (5 downto 0);
signal OneUSClk: std_logic:='0';
signal sclk_out_tick1: std_logic:='0';
signal sclk_out_tick2: std_logic:='0';
signal sclk_out_tick3: std_logic:='0';
signal sclk_out_tick_p: std_logic:='0';
signal sclk_out_tick_p2: std_logic:='0';
signal sclk_out_tick_p3: std_logic:='0';
signal idle_load: std_logic:='0';
-- shift register
signal r_reg: std_logic_vector(N-1 downto 0);
signal r_next: std_logic_vector(N-1 downto 0);
signal ctrl: std_logic_vector(1 downto 0);
-- ready
signal ready: std_logic:='0';
--**************************************************************************
-- STATE MACHINE SIGNAL DECLARATION:
type StateType is (
idle,
send_data
);
signal CurrentState, NextState : StateType;
--**************************************************************************
begin
COMB: process(CurrentState ,W , counter_8clk,sclk_out_tick_p3) --leave_signal
begin
case CurrentState is
when idle =>
if (W = '1') then
NextState <= send_data;
else
NextState <= idle;
end if;
when send_data =>
if ((sclk_out_tick_p3 = '1') and (counter_8clk = "0000" ))then
NextState <= idle;
else
NextState <= send_data;
end if;
end case;
end process COMB;
SEQ: process(reset, clk)
begin
if(reset = '1') then
CurrentState <= idle;
elsif (clk'event and clk = '1') then
CurrentState <= NextState;
end if;
end process SEQ;
with CurrentState select
counter_reset <= '1' when idle,
'0' when send_data,
'1' when Others;
with CurrentState select
ctrl <= "11" when idle,
"10" when send_data,
"11" when others;
with CurrentState select
ready <= '1' when idle,
'0' when send_data,
'0' when others;
with CurrentState select
idle_load <= '1' when idle,
'0' when others;
ready_out <= ready;
--**************************************************************************
-- 4 bit counter - 8 times count
--**************************************************************************
process(reset, clk, counter_reset,sclk_out_tick_p,counter_8clk)
begin
if(reset = '1') then
counter_8clk <= "1001";
counter_8clk_tick <= '0';
elsif (counter_reset = '1') then
counter_8clk <= "1000";
counter_8clk_tick <= '0';
elsif (counter_reset = '1') then
elsif (clk = '1' and clk'event) then
if (sclk_out_tick_p = '1') then
if (counter_8clk = "0010") then -- Terminal Count value
counter_8clk_tick <= '1';
counter_8clk <= counter_8clk - 1;
else
counter_8clk <= counter_8clk - 1;
counter_8clk_tick <= '0';
end if;
end if;
end if;
end process;
--**************************************************************************
-- 6 bit counter - 38 times count
--**************************************************************************
process (clk,reset,clkCount,counter_reset)
begin
if ((reset = '1') or (counter_reset = '1')) then
clkCount <= "100110"; --38
sclk_out_tick1 <= '1';
OneUSClk <= '0';
elsif (clk = '1' and clk'event) then
if(clkCount = "100110") then -- 38
clkCount <= "000000";
oneUSClk <= not oneUSClk;
sclk_out_tick3 <= '0';
sclk_out_tick1 <= '1';
elsif (clkCount = "100100") then --36
sclk_out_tick2 <= '1';
clkCount <= clkCount + 1;
sclk_out_tick3 <= '0';
elsif (clkCount = "100101") then -- 37
sclk_out_tick3 <= '1';
sclk_out_tick2 <= '0';
clkCount <= clkCount + 1;
else
clkCount <= clkCount + 1;
sclk_out_tick1 <= '0';
sclk_out_tick2 <= '0';
sclk_out_tick3 <= '0';
end if;
end if;
end process;
clock_38 <= oneUSClk;
sclk_out_tick_p <= '1' when sclk_out_tick1 = '1' and oneUSClk = '1' else '0';
sclk_out_tick_p2 <= '1' when sclk_out_tick2 = '1' and oneUSClk = '0' else '0';
sclk_out_tick_p3 <= '1' when sclk_out_tick3 = '1' and oneUSClk = '0' else '0';
--**************************************************************************
-- shift register
--**************************************************************************
-- register
process(clk,reset,sclk_out_tick1,sclk_out_tick_p,idle_load,data)
begin
if (reset='1') then
r_reg <= data;
elsif (clk'event and clk='1') then
if (sclk_out_tick_p2 = '1' ) or (idle_load = '1') then
r_reg <= r_next;
end if;
end if;
end process;
with ctrl select
r_next <=
r_reg when "00", --no op
r_reg(N-2 downto 0) & data(0) when "01", --shift left;
data(N-1) & r_reg(N-1 downto 1) when "10", --shift right;
data when others; -- load
serial_out <= r_reg(0);
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity spi_forum is
generic(N: integer := 8);
port(
clk, reset, W: in std_logic;
data: in std_logic_vector(N-1 downto 0);
ready_out: out std_logic;
clock_38: out std_logic;
serial_out: out std_logic
);
end spi_forum;
architecture Behavioral of spi_forum is
--signals
signal counter_8clk : std_logic_vector(3 downto 0);
signal counter_8clk_tick : std_logic:='0';
signal counter_reset : std_logic:='0';
--clock_divided
signal clkCount: std_logic_vector (5 downto 0);
signal OneUSClk: std_logic:='0';
signal sclk_out_tick1: std_logic:='0';
signal sclk_out_tick2: std_logic:='0';
signal sclk_out_tick3: std_logic:='0';
signal sclk_out_tick_p: std_logic:='0';
signal sclk_out_tick_p2: std_logic:='0';
signal sclk_out_tick_p3: std_logic:='0';
signal idle_load: std_logic:='0';
-- shift register
signal r_reg: std_logic_vector(N-1 downto 0);
signal r_next: std_logic_vector(N-1 downto 0);
signal ctrl: std_logic_vector(1 downto 0);
-- ready
signal ready: std_logic:='0';
--**************************************************************************
-- STATE MACHINE SIGNAL DECLARATION:
type StateType is (
idle,
send_data
);
signal CurrentState, NextState : StateType;
--**************************************************************************
begin
COMB: process(CurrentState ,W , counter_8clk,sclk_out_tick_p3) --leave_signal
begin
case CurrentState is
when idle =>
if (W = '1') then
NextState <= send_data;
else
NextState <= idle;
end if;
when send_data =>
if ((sclk_out_tick_p3 = '1') and (counter_8clk = "0000" ))then
NextState <= idle;
else
NextState <= send_data;
end if;
end case;
end process COMB;
SEQ: process(reset, clk)
begin
if(reset = '1') then
CurrentState <= idle;
elsif (clk'event and clk = '1') then
CurrentState <= NextState;
end if;
end process SEQ;
with CurrentState select
counter_reset <= '1' when idle,
'0' when send_data,
'1' when Others;
with CurrentState select
ctrl <= "11" when idle,
"10" when send_data,
"11" when others;
with CurrentState select
ready <= '1' when idle,
'0' when send_data,
'0' when others;
with CurrentState select
idle_load <= '1' when idle,
'0' when others;
ready_out <= ready;
--**************************************************************************
-- 4 bit counter - 8 times count
--**************************************************************************
process(reset, clk, counter_reset,sclk_out_tick_p,counter_8clk)
begin
if(reset = '1') then
counter_8clk <= "1001";
counter_8clk_tick <= '0';
elsif (counter_reset = '1') then
--counter_8clk <= (others=>'0');
counter_8clk <= "1000";
counter_8clk_tick <= '0';
elsif (counter_reset = '1') then
elsif (clk = '1' and clk'event) then
if (sclk_out_tick_p = '1') then
if (counter_8clk = "0010") then -- Terminal Count value
-- counter_8clk <= (others=>'0');
counter_8clk_tick <= '1';
counter_8clk <= counter_8clk - 1;
else
counter_8clk <= counter_8clk - 1;
counter_8clk_tick <= '0';
end if;
end if;
end if;
end process;
--**************************************************************************
-- 6 bit counter - 38 times count
--**************************************************************************
process (clk,reset,clkCount2,counter_reset2)
begin
if (reset = '1') then
clkCount2 <= "100111"; --38
sclk_out_tick1_1 <= '1';
OneUSClk2 <= '0';
elsif (counter_reset2 = '1') then
clkCount2 <= "100111"; --38
elsif (clk = '1' and clk'event) then
if(clkCount2 = "100111") then -- 38
oneUSClk2 <= not oneUSClk2;
clkCount2 <= clkCount2 - 1;
sclk_out_tick3_1 <= '0';
sclk_out_tick1_1 <= '1';
elsif (clkCount2 = "000010") then --2
sclk_out_tick2_1 <= '1';
clkCount2 <= clkCount2 - 1;
sclk_out_tick3_1 <= '0';
elsif (clkCount2 = "000001") then -- 37
sclk_out_tick3_1 <= '1';
sclk_out_tick2_1 <= '0';
clkCount2 <= clkCount2 - 1;
else
clkCount2 <= clkCount2 - 1;
sclk_out_tick1_1 <= '0';
sclk_out_tick2_1 <= '0';
sclk_out_tick3_1 <= '0';
end if;
end if;
end process;
clock_38 <= oneUSClk;
sclk_out_tick_p <= '1' when sclk_out_tick1 = '1' and oneUSClk = '1' else '0';
sclk_out_tick_p2 <= '1' when sclk_out_tick2 = '1' and oneUSClk = '0' else '0';
sclk_out_tick_p3 <= '1' when sclk_out_tick3 = '1' and oneUSClk = '0' else '0';
--**************************************************************************
-- shift register
--**************************************************************************
-- register
process(clk,reset,sclk_out_tick1,sclk_out_tick_p,idle_load,data)
begin
if (reset='1') then
r_reg <= data;
elsif (clk'event and clk='1') then
if ((sclk_out_tick_p2 = '1' and counter_8clk >= "000001" ) or (idle_load = '1')) then
r_reg <= r_next;
end if;
end if;
end process;
with ctrl select
r_next <=
r_reg when "00", --no op
r_reg(N-2 downto 0) & data(0) when "01", --shift left;
data(N-1) & r_reg(N-1 downto 1) when "10", --shift right;
data when others; -- load
serial_out <= r_reg(0);
end Behavioral;
Thanks! I can see clearly sync reset but I need to read some more on the async one in order to be able to implement it