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.

VHDL--- Convert multiple architectures into a single architecture and get serial data

Status
Not open for further replies.

uselessmail

Junior Member level 3
Joined
Mar 6, 2012
Messages
28
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,479
Hi there!
I have made a simple program to generate an MLS signal (Maximum length Sequence). Its a type of a PRBS signal with some additional properties. In the code, I found it easier to simply write three different architectures in the same entity. I was wondering if I could probably write the entire code within a single architecture. Is there any benefit of doing so? Or is easier to just keep the code as it is?
Also, I need to get the digital output serially through a single port, for eg through the SMA connector on my board. But I cant do that since the output is stored in a signal array of 0 to 9 and I'm only able to connect it to 10 different output ports!
In other words, I need an output from a single SMA connector which will look something like this...
PRBS.gif

Hope someone can help me figure this out!

Code:
entity mlbs is
    Port ( clock : in  STD_LOGIC;
           reset : in  STD_LOGIC;
           data_out : inout  STD_LOGIC_VECTOR (9 downto 0) );
end mlbs;

architecture Behavioral of mlbs is
component mlbs_clk
port
 (-- Clock in ports
  CLK_IN1           : in     std_logic;
  -- Clock out ports
  CLK_OUT1          : out    std_logic
 );
end component;

signal clk_out : std_logic;
signal lfsr_reg : std_logic_vector (9 downto 0);

begin

clkmodle1 : mlbs_clk
  port map
   (-- Clock in ports
    CLK_IN1 => clock,
    -- Clock out ports
    CLK_OUT1 => clk_out);

	process(clk_out)
		variable lfsr_tap: std_logic;
	begin
		
		if rising_edge(clk_out) then
			if reset = '1' then
				lfsr_reg <= (others => '1');
			else
				lfsr_tap := lfsr_reg(6) xor lfsr_reg(9);
				lfsr_reg <= lfsr_reg(8 downto 0) & lfsr_tap;
			end if;
		end if;
	end process;
	
	data_out <= lfsr_reg;
	
end Behavioral;


architecture Behavioral_2 of mlbs is
component mlbs_clk
port
 (-- Clock in ports
  CLK_IN1           : in     std_logic;
  -- Clock out ports
  CLK_OUT1          : out    std_logic
 );
end component;

signal clk_out : std_logic;
signal lfsr_reg : std_logic_vector (9 downto 0);

begin

clkmodle2 : mlbs_clk
  port map
   (-- Clock in ports
    CLK_IN1 => clock,
    -- Clock out ports
    CLK_OUT1 => clk_out);
	 
	process(clk_out)
		variable lfsr_tap: std_logic;
	begin
		
		if rising_edge(clk_out) then
			if reset = '1' then
				lfsr_reg <= (others => '1');
			else
				lfsr_tap := lfsr_reg(3) xor lfsr_reg(5);
				lfsr_reg <= lfsr_reg(8 downto 0) & lfsr_tap;
			end if;
		end if;
	end process;
	
	data_out <= lfsr_reg;
end Behavioral_2;



architecture Behavioral_3 of mlbs is
component mlbs_clk
port
 (-- Clock in ports
  CLK_IN1           : in     std_logic;
  -- Clock out ports
  CLK_OUT1          : out    std_logic
 );
end component;

signal clk_out : std_logic;
signal lfsr_reg : std_logic_vector (9 downto 0);

begin

clkmodle3 : mlbs_clk
  port map
   (-- Clock in ports
    CLK_IN1 => clock,
    -- Clock out ports
    CLK_OUT1 => clk_out);

	process(clk_out)
		variable lfsr_tap: std_logic;
	begin
		
		if rising_edge(clk_out) then
			if reset = '1' then
				lfsr_reg <= (others => '1');
			else
				lfsr_tap := lfsr_reg(1) xor lfsr_reg(6);
				lfsr_reg <= lfsr_reg(8 downto 0) & lfsr_tap;
			end if;
		end if;
	end process;
	
	data_out <= lfsr_reg;
	
end Behavioral_3;
 

all 3 architectures seem to do the same thing, other than move the taps around.
You probably want to look at generics and generate statements to do this. Using configurations to load the correct architecture is a bit of a bind. Multiple architectures are really meant for completly different implementations. eg. a simulation model version and a synthesis version of a design.
 

You probably want to look at generics and generate statements to do this.

Could you kindly help me out with that! I saw a few examples using generate statements but I'm still not clear as to how I can do it in my case. I'd appreciate your patience on this!

Thank you!
 

Have the two tap positions as generics?


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
entity mlbs is
  generic (
    TAP1_SEL : natural;
    TAP2_SEL : natural
  );
 
 
....
 
lfsr_tap := lfsr_reg(TAP1_SEL) xor lfsr_reg(TAP2_SEL);

 

Have the two tap positions as generics?


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
entity mlbs is
  generic (
    TAP1_SEL : natural;
    TAP2_SEL : natural
  );
 
 
....
 
lfsr_tap := lfsr_reg(TAP1_SEL) xor lfsr_reg(TAP2_SEL);


Ok and then how do I change the Tap1_SEL and TAP2_SEL values at every iteration? Do I need to put it in a loop?
 

What iterations?
If you mean different builds, you just change the values in the source code.
If you mean while the code is running, you cannot change them - they are fixed at compile time. You will need to re-think your circuit with muxes to select different tap points.
The origional code showd different architectures - you can only instantiate one of these (hence the generics offering).
 

What iterations?
If you mean different builds, you just change the values in the source code.

Thank you for that!I got what you meant!
How do I get to output the data serially though? I tried using the following code but got a multiple driver error
Code:
LED_OUT <= lfsr_reg(9);
lfsr_reg(9 downto 1) <= lfsr_reg(8 downto 0);

In this code lfsr_reg is being written into twice. Once in the code
Code:
if reset = '1' then
lfsr_reg <= (others => '1');

and then in the code I wrote above. Could you please explain how I can get around this problem?
 

Code:
entity mlbs is
	
	generic(
			TAP1_SEL : natural:= 3;
			TAP2_SEL : natural:= 5);
			
    Port ( clock : in  STD_LOGIC;
           reset : in  STD_LOGIC;
           data_out : out  STD_LOGIC_VECTOR (9 downto 0);
	   LED_OUT: out STD_LOGIC);

end mlbs;

architecture Behavioral of mlbs is
component mlbs_clk
port
 (-- Clock in ports
  CLK_IN1           : in     std_logic;
  -- Clock out ports
  CLK_OUT1          : out    std_logic
 );
end component;

signal clk_out : std_logic;
signal lfsr_reg : std_logic_vector (9 downto 0);

begin

clkmodle1 : mlbs_clk
  port map
   (-- Clock in ports
    CLK_IN1 => clock,
    -- Clock out ports
    CLK_OUT1 => clk_out);

	process(clk_out)
		variable lfsr_tap: std_logic;
	begin
		
		if rising_edge(clk_out) then
			if reset = '1' then
				lfsr_reg <= (others => '1');
			else
				lfsr_tap := lfsr_reg(TAP1_SEL) xor lfsr_reg(TAP2_SEL);
				lfsr_reg <= lfsr_reg(8 downto 0) & lfsr_tap;
			end if;
		end if;
	end process;
	
	data_out <= lfsr_reg;
	
	LED_OUT <= lfsr_reg(9);
	lfsr_reg(9 downto 1) <= lfsr_reg(8 downto 0);
	
	
end Behavioral;
 

Apart from the multiple driver error, the additional shift register is pretty useless.

Connecting an dataout bit of your choice as serial output is all you need to do. It represents the full prbs information.
 

Apart from the multiple driver error, the additional shift register is pretty useless.

Connecting an dataout bit of your choice as serial output is all you need to do. It represents the full prbs information.

Well I tried that but I am not getting the output as I need. I am obviously getting just that one bit as output. What I need as an output is something like this:
PRBS.gif

Right now all I am getting is a straight DC line! I am taking the output at data_out[0]. (I also tried at data_out[6] and data_out[9]).
 

I had previously written a similar code for generation of a normal PRBS using D flip flops. I implemented the LED_OUT there without any problem. The code for that one was:

Code:
entity mlbs is
    Port ( clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           data_out : out  STD_LOGIC_VECTOR (15 downto 0);
			  LED_OUT: out std_logic);
end mlbs;

architecture Behavioral of mlbs is

component dff
Port ( clk: in std_logic;
		 rst: in std_logic;
		 D: in std_logic;
		 Q: out std_logic);
		 
end component;

component clk_core
port
 (-- Clock in ports
  CLK_IN1           : in     std_logic;
  -- Clock out ports
  CLK_OUT1          : out    std_logic
 );
end component;

signal data_reg: std_logic_vector (15 downto 0);
signal tap_data: std_logic;
signal clk_out: std_logic;

begin

	process(data_reg, tap_data, clk_out)
	
		begin
				tap_data <= (data_reg(1) xor data_reg(2)) xor (data_reg(4) xor data_reg(15));
			
				
	end process;
	
mlbs_clock : clk_core
  port map
   (-- Clock in ports
    CLK_IN1 => clk,
    -- Clock out ports
    CLK_OUT1 => clk_out);

	
	stage0: dff
			port map(clk_out, rst, tap_data, data_reg(0));

		
		
	data_out <= data_reg;	
	
	process(clk_out)
	begin
	if rising_edge(clk_out) then
	
				LED_OUT <= data_reg(15);
				data_reg(15 downto 1) <= data_reg(14 downto 0);
	
	end if;
		end process;


end Behavioral;

___________________________________________________________________________________
For my D Flip flop:


entity dff is
    Port ( clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           D : in  STD_LOGIC;
           Q : out  STD_LOGIC);
end dff;

architecture Behavioral of dff is

begin

	process(clk)
	begin
			if rising_edge(clk) then
				
				if rst= '1' then
					Q <= '1';
				
				else
					Q <= D;
				end if;
				
			end if;
			
	end process;

end Behavioral;


Now how do I get a similar result for my MLS code??
 

I wout expect both LED_OUT and any bit of data_out to provide the intended PRBS stream. The frequency may be too high to see anything useful however.
 

I wout expect both LED_OUT and any bit of data_out to provide the intended PRBS stream. The frequency may be too high to see anything useful however.

Well I was initially trying to get the output at 100 MHz. I changed it to 20 MHz but the result is still the same. I'm getting a High DC line. Thats all!:sad:
 

I'm not sure about the POR register level in your synthesized design. If it's all zero, a reset signal is required to start the generator.
 

I'm not sure about the POR register level in your synthesized design. If it's all zero, a reset signal is required to start the generator.

So, should I initialize my Reset signal to '1' in the beginning? Then I'll need to change it though, right?
 

I was talking about initial level of registers, not reset level. Please check yourself for the necessary requirements. In case of doubt, use debug tools like Chipscope/Signal Tap or what's available with your FPGA familiy to identify the problem.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top