Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[moved] Shift Register and Serial-In Parallel Out converter

Status
Not open for further replies.

mwb

Junior Member level 2
Joined
Jul 20, 2015
Messages
21
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,469
Im taping out a chip that requires a robust serial-to-parallel converter. What is posted below seems to synthesize correctly but I have the following questions:

I use asynchronous resets because there are two clocks, p_clk and clk. clk shifts in the serial data, p_clk latches it out.
Async. resets obviously gives better timing and since I control the data-in, reset, p_clk and clk from off-chip, I don't think I will have problems with reset-recovery timing. I have to admit, reset-recovery time is a new concept to me, I mainly work on FPGA's and this is never an issue since the tools take that worry away. In this case, Im on my own synthesizing with standard cells and DC-shell.

Lastly, the shift-reg input:
Code:
        sr(data_width - 1 downto 0) <= sr(data_width - 2 downto 0) & serial_data_in;
        vec_mod_slow_in             <= sr;

looks like it might function more reliably if I reversed the order so that the output register vec_mod_slow_in is always defined since the synthesis tool does not support initial values:

Code:
   vec_mod_slow_in             <= sr;
   sr(data_width - 1 downto 0) <= sr(data_width - 2 downto 0) & serial_data_in;

The circuit synthesizes and functions perfectly. There is a two clk period lag before I can latch the data into the slow_registers but this is fine. It seems to improve timing, not exactly sure why.

I'd just like some opinions on this if anyone has any.

Thanks.


Code:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;

use work.mwb.all;

entity WVFRM_GEN is

  generic (
    data_width : integer := 68;
    bank_width : integer := 17;
    num_banks  : integer := 4
    );
  port (
    clk             : in  std_logic;
    p_clk           : in  std_logic;
    serial_data_in  : in  std_logic;
    reset           : in  std_logic;
    serial_data_out : out std_logic;

    vm_a_en     : out std_logic_vector(11 downto 0);
    vm_a_en_bar : out std_logic_vector(11 downto 0);
    vm_b_en     : out std_logic_vector(11 downto 0);
    vm_b_en_bar : out std_logic_vector(11 downto 0);
    vm_c_en     : out std_logic_vector(11 downto 0);
    vm_c_en_bar : out std_logic_vector(11 downto 0);
    vm_d_en     : out std_logic_vector(11 downto 0);
    vm_d_en_bar : out std_logic_vector(11 downto 0);

    vm_a_s_i            : out std_logic;
    vm_a_s_i_bar        : out std_logic;
    vm_b_s_i            : out std_logic;
    vm_b_s_i_bar        : out std_logic;
    vm_c_s_i            : out std_logic;
    vm_c_s_i_bar        : out std_logic;
    vm_d_s_i            : out std_logic;
    vm_d_s_i_bar        : out std_logic;
    vm_a_sign_i_lsb     : out std_logic;
    vm_a_sign_i_lsb_bar : out std_logic;
    vm_b_sign_i_lsb     : out std_logic;
    vm_b_sign_i_lsb_bar : out std_logic;
    vm_c_sign_i_lsb     : out std_logic;
    vm_c_sign_i_lsb_bar : out std_logic;
    vm_d_sign_i_lsb     : out std_logic;
    vm_d_sign_i_lsb_bar : out std_logic;
    vm_a_s_q            : out std_logic;
    vm_a_s_q_bar        : out std_logic;
    vm_b_s_q            : out std_logic;
    vm_b_s_q_bar        : out std_logic;
    vm_c_s_q            : out std_logic;
    vm_c_s_q_bar        : out std_logic;
    vm_d_s_q            : out std_logic;
    vm_d_s_q_bar        : out std_logic;
    vm_a_sign_q_lsb     : out std_logic;
    vm_a_sign_q_lsb_bar : out std_logic;
    vm_b_sign_q_lsb     : out std_logic;
    vm_b_sign_q_lsb_bar : out std_logic;
    vm_c_sign_q_lsb     : out std_logic;
    vm_c_sign_q_lsb_bar : out std_logic;
    vm_d_sign_q_lsb     : out std_logic;
    vm_d_sign_q_lsb_bar : out std_logic;

    vm_a_sign_msb     : out std_logic;
    vm_a_sign_msb_bar : out std_logic;
    vm_b_sign_msb     : out std_logic;
    vm_b_sign_msb_bar : out std_logic;
    vm_c_sign_msb     : out std_logic;
    vm_c_sign_msb_bar : out std_logic;
    vm_d_sign_msb     : out std_logic;
    vm_d_sign_msb_bar : out std_logic
    );
end entity WVFRM_GEN;

architecture behavioral of WVFRM_GEN is

  signal sr         : std_logic_vector(data_width - 1 downto 0) := (others => '0');
  signal serial_out : std_logic                                 := '0';

  -----------------------------------------------------------------------------


  signal vec_mod_slow_in : std_logic_vector(data_width - 1 downto 0) := (others => '0');
  signal parallel_out    : std_logic_vector(data_width - 1 downto 0) := (others => '0');

  signal vec_mod_out_reclk_1        : std_logic_vector(data_width - 1 downto 0) := (others => '0');
  signal vec_mod_out_reclk_2        : std_logic_vector(data_width - 1 downto 0) := (others => '0');
  signal vec_mod_out_reclk_post_mux : std_logic_vector(data_width - 1 downto 0) := (others => '0');  -- <[comment]>
-- signal test_pattern : std_logic_vector(data_width - 1 downto 0) := "11110000101000001011000011000000011101100101010000110010000100001001";  -- test pattern
begin  -- behavioral

  --- vec_mod_out_reclk_post_mux <= vec_mod_out_reclk_2 when output_enable = '1' else test_pattern;

  vm_a_en     <= vec_mod_out_reclk_2(67 downto 56);
  vm_a_en_bar <= not vec_mod_out_reclk_2(67 downto 56);
  vm_b_en     <= vec_mod_out_reclk_2(50 downto 39);
  vm_b_en_bar <= not vec_mod_out_reclk_2(50 downto 39);
  vm_c_en     <= vec_mod_out_reclk_2(33 downto 22);
  vm_c_en_bar <= not vec_mod_out_reclk_2(33 downto 22);
  vm_d_en     <= vec_mod_out_reclk_2(16 downto 5);
  vm_d_en_bar <= not vec_mod_out_reclk_2(16 downto 5);

  vm_a_s_i     <= vec_mod_out_reclk_2(55);
  vm_a_s_i_bar <= not vec_mod_out_reclk_2(55);
  vm_b_s_i     <= vec_mod_out_reclk_2(38);
  vm_b_s_i_bar <= not vec_mod_out_reclk_2(38);
  vm_c_s_i     <= vec_mod_out_reclk_2(21);
  vm_c_s_i_bar <= not vec_mod_out_reclk_2(21);
  vm_d_s_i     <= vec_mod_out_reclk_2(4);
  vm_d_s_i_bar <= not vec_mod_out_reclk_2(4);

  vm_a_sign_i_lsb     <= vec_mod_out_reclk_2(54);
  vm_a_sign_i_lsb_bar <= not vec_mod_out_reclk_2(54);
  vm_b_sign_i_lsb     <= vec_mod_out_reclk_2(37);
  vm_b_sign_i_lsb_bar <= not vec_mod_out_reclk_2(37);
  vm_c_sign_i_lsb     <= vec_mod_out_reclk_2(20);
  vm_c_sign_i_lsb_bar <= not vec_mod_out_reclk_2(20);
  vm_d_sign_i_lsb     <= vec_mod_out_reclk_2(3);
  vm_d_sign_i_lsb_bar <= not vec_mod_out_reclk_2(3);

  vm_a_s_q     <= vec_mod_out_reclk_2(53);
  vm_a_s_q_bar <= not vec_mod_out_reclk_2(53);
  vm_b_s_q     <= vec_mod_out_reclk_2(36);
  vm_b_s_q_bar <= not vec_mod_out_reclk_2(36);
  vm_c_s_q     <= vec_mod_out_reclk_2(19);
  vm_c_s_q_bar <= not vec_mod_out_reclk_2(19);
  vm_d_s_q     <= vec_mod_out_reclk_2(2);
  vm_d_s_q_bar <= not vec_mod_out_reclk_2(2);

  vm_a_sign_q_lsb     <= vec_mod_out_reclk_2(52);
  vm_a_sign_q_lsb_bar <= not vec_mod_out_reclk_2(52);
  vm_b_sign_q_lsb     <= vec_mod_out_reclk_2(35);
  vm_b_sign_q_lsb_bar <= not vec_mod_out_reclk_2(35);
  vm_c_sign_q_lsb     <= vec_mod_out_reclk_2(18);
  vm_c_sign_q_lsb_bar <= not vec_mod_out_reclk_2(18);
  vm_d_sign_q_lsb     <= vec_mod_out_reclk_2(1);
  vm_d_sign_q_lsb_bar <= not vec_mod_out_reclk_2(1);

  vm_a_sign_msb     <= vec_mod_out_reclk_2(51);
  vm_a_sign_msb_bar <= not vec_mod_out_reclk_2(51);
  vm_b_sign_msb     <= vec_mod_out_reclk_2(34);
  vm_b_sign_msb_bar <= not vec_mod_out_reclk_2(34);
  vm_c_sign_msb     <= vec_mod_out_reclk_2(17);
  vm_c_sign_msb_bar <= not vec_mod_out_reclk_2(17);
  vm_d_sign_msb     <= vec_mod_out_reclk_2(0);
  vm_d_sign_msb_bar <= not vec_mod_out_reclk_2(0);


  dff_1 : process(p_clk, reset)
  begin

    if reset = '0' then
      if rising_edge(p_clk) then

        vec_mod_out_reclk_1 <= vec_mod_slow_in;
      end if;
    else
      vec_mod_out_reclk_1 <= (others => '0');
    end if;
  end process dff_1;

  dff_2 : process(p_clk, reset)
  begin

    if reset = '0' then

      if rising_edge(p_clk) then

        vec_mod_out_reclk_2 <= vec_mod_out_reclk_1;
      end if;
    else

      vec_mod_out_reclk_2 <= (others => '0');
    end if;
  end process dff_2;


--vec_mod_out <= vec_mod_out_reclk_2;


--vec_mod_out_bar <= not vec_mod_out_reclk_2;



  --fast_latch : process(clk, reset)
  --begin

  --  if reset = '0' then

  --    -- need to double check these states and possible double-dff for the crossing clock domains.

  --    if rising_edge(clk) then
  --      vec_mod_slow_in <= 
  --    end if;
  --  else
  --    vec_mod_slow_in <= (others => '0');
  --  end if;
  --end process fast_latch;

  serial_data_out <= serial_out;
    serial_out <= sr(data_width - 1);

  process(clk, reset)
  begin


    if reset = '0' then
      if rising_edge(clk) then
        sr(data_width - 1 downto 0) <= sr(data_width - 2 downto 0) & serial_data_in;
        vec_mod_slow_in             <= sr;
      end if;
    else
      sr(data_width - 1 downto 0) <= (others => '0');

    end if;

  end process;

end behavioral;
 
Last edited by a moderator:

Re: Shift Register and Serial-In Parallel Out converter

You don't seem to have a good grasp of VHDL if you think that switching the order of vec_mod_slow_in and sr is going to result in different circuits...It won't.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top