Applying simple inversion (NOT function) to OBUFDS - fpga

I am a newbie here to ask a question, that is too easy for you to answer, but I am not familiar with.
I have "cabletester_prbs15_bytegenerator" IP in my BD, which has "data_out_p" and "data_out_n" connected to OBUFDS ports.
In my situation I have an OBUFDS connected to "data_out_p", but assign to NEGATIVE DIFFERENTIAL LEG in implementation. At the moment, after successful synthesis, when I try to assign it to IO_##_N in synthesis design, It gives error message "cannot set LOC property of ports, the negative port (N-side) of a differential pair can not be placed on a positive Pin"
Long story short, I need to invert polarity of OBUFDS.
cabletester_prbs15_bytegenerator IP uses module "prbs15_bytegenerator" like below.
module cabletester_prbs15_bytegenerator_0_0 (
clk,
clk_div4,
resetb,
data_out_p,
data_out_n
);
(* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME clk, ASSOCIATED_RESET resetb:reset, FREQ_HZ 640000000, FREQ_TOLERANCE_HZ 0, PHASE 0.0, CLK_DOMAIN cabletester_clk_wiz_0_0_clk_320, INSERT_VIP 0" *)
(* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 clk CLK" *)
input wire clk;
input wire clk_div4;
(* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME reset, POLARITY ACTIVE_LOW, INSERT_VIP 0" *)
(* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 reset RST" *)
input wire resetb;
output wire data_out_p;
output wire data_out_n;
prbs15_bytegenerator inst (
.clk(clk),
.clk_div4(clk_div4),
.resetb(resetb),
.data_out_p(data_out_p),
.data_out_n(data_out_n)
);
endmodule
In prbs15_bytegenerator, you can see OBUFDS relevant part at the end
OSERDESE3 #(
.DATA_WIDTH(8),
.IS_CLKDIV_INVERTED(0),
.IS_CLK_INVERTED(0),
.IS_RST_INVERTED(1),
.SIM_DEVICE("ULTRASCALE_PLUS")
)
oserdes_inst
(
.OQ(data_out),
.CLK(clk),
.CLKDIV(clk_div4),
.D(prbsbyte),
.RST(resetb)
);
OBUFDS outputbuf
(
.I(data_out),
.O(data_out_p),
.OB(data_out_n)
);
endmodule
Is inverting the polarity just as simple as putting ~ in front of .O(data_out_p)?
I would really appreciate if one could show what the code should exactly look like cuz I know very little about Verilog.....
Thank you so much....

You probably want to keep the polarity of the OBUFDS correctly orientated. P to positive leg, and N to negative leg. Instead, try invering the input to the OBUFDS by making the following tweak.
OBUFDS outputbuf
(
.I(~data_out), // This will invert the input and cause the
.O(data_out_p), // output to logically invert.
.OB(data_out_n)
);

You might have a problem with your pin assignment. You should review the XDC constraint file.
Or, here post your constraint with the device part number.

Related

Signal in Top Module of a design being driven by two drivers (from different components)

In my design I have several modules. the code snippet of the top module is coming as follows.
There's one problem which confuses me. let's assume the below scenario:
Step1:
The Calc1_module works from t1 to t2 and it should send it's output to the input of the memory module to be stored there. (Calc1_out is mapped to Aggregation_Signal)
Step2:
The Calc2_module works from t3 to t4 and it should send it's output to the input of the memory module to be stored there. (Calc2_out is mapped to Aggregation_Signal).
The Memory_Moduel_in is mapped to Aggregation_Signal.
Since there are multiple drivers for one signal, it has all the time an unknown value.
It's worth mentioning that all controls occur within FSM to decide when it goes after Calc1 and when Calc2.
How I can selectively interleave different data from different sources on one wire (signal) on at a time -in the top module of the design- without pushing that wire into an unknown state?
In other words, how is it possible to aggregate:
value1 for signal1 (e.g. coming from Calc2 in t1 to t2)
value2 from signal2 (e.g. coming from Calc1 in t2 to t3)
all in one Aggregation_Signal without driving it into unknown state.
entity TOP is
port (...);
end entity;
architecture Behav_TOP of TOP is
component FSM is
port(...);
end component;
component Calc1_Module is
port
( ...
Calc1_Module_out
... );
end component;
component Calc2_Module is
port
( ...
Calc2_Module_out
... );
end component;
component Memory_Module is
port
( ...
Memory_Module_in
... );
end component;
Signal Aggregation_Signal;
begin
U_FSM : FSM
port map(...);
U_Calc1_Module : Calc1_Module
port map
( ...
Calc1_Module_out => Aggregation_Signal,
... );
U_Calc2_Module : Calc2_Module
port map
( ...
Calc2_Module_out => Aggregation_Signal,
... );
U_Memory_Module : Memory_Module
port map
( ...
Memory_Module_in => Aggregation_Signal,
... );
end Behav_TOP;
The clue is in your term "selectively interleave".
How do you make that selection? Presumably you know when you want to see Calc1, when you want to see Calc2, etc. So encode that information onto a signal, let's call it Selector.
Then bring each unit's output onto its own signal, Calc1_output etc and use Selector to select between them onto Aggregation_Signal.
Aggregation_Signal <= Calc1_output when Selector = Calc1
else Calc2_output when Selector = Calc2
else (others => '0';
The Selector signal can be an enumeration with one value per Calc unit, or a Natural or a std_logic_vector with constants named Calc1, Calc2 etc.
Since you say the calculation is driven by a state machine, it is logical for the state machine to drive Selector with the correct value whenever you need a value on Aggregation_Signal.

VHDL process does not synthesize as expected

I have a bit of trivial looking VHDL code which is driving me crazy. I have an external logic bit connected to a signal called 'inint'. The signal is then used in a process that looks as follows:
process(inint)
begin
if rising_edge(inint) then
extint <= '1';
end if;
if falling_edge(inint) then
extint <= '0';
end if;
end process;
When I synthesize tis code though, only the lower part of the code is synthesized and not the upper part. What am I missing here?
I am guessing it is something very elementary but cannot put a finger on it. Any help would be greatly appreciated.
Regards,
Shailesh
The correct way to do this is with a double data rate register. Otherwise you can't synthesize logic that toggles at the clock rate. The Xilinx primitive you need is called an ODDR and is documented in the Select IO Resources User guide for your device (here is the one for the Artix-7, see page 127).
It can be instantiated to do what you're trying to do like this:
ODDR_INST1 : ODDR
generic map (
DDR_CLK_EDGE => "SAME_EDGE",
INIT => '0',
SRTYPE => "SYNC"
)
port map (
Q => extint,
C => inint,
CE => '1',
D1 => '1',
D2 => '0',
R => '0',
S => '0'
);
As an added note trying to imply a double data rate output (which is what your code does) is not a good idea. Its probably not supported, but also as a general rule if you need special purpose hardware (which you do), you should instantiate it directly because its hard to guarantee when the tools will infer (though they are much more deterministic than they used to be).

SystemVerilog random data generated only for valid signal

I am new to SV and would like to get some opinions about randomization. I have two signals.
rand bit [20:0] data;
rand bit data_valid;
I want to generate random data only when data_valid signal goes high. When valid signal is low, data should contain the previous signal. I have tried the following on
constraint valid_data {data -> data_valid ==1'b1; }
It generates random data when valid signal is high but then data becomes 0 when valid signal goes low. Is there any other way to do that? What I want is data signal should not change when valid becomes low. It should keep the current value of valid signal goes low.
Another issue is the randomization of data_valid signal. This is a 1 bit signal and I want to make this signal high randomly for 1 clock cycle only. At the moment it can remain high for any clock cycles which I don't want.
You need to build a state machine by saving a copy of the previously generated values
class tx;
rand bit [20:0] data;
rand bit data_valid;
bit [20:0] prev_data;
bit prev_data_valid;
function void post_randomize;
prev_data = data;
prev_data_valid = data_valid;
endfunction
constraint one_cycle { prev_data_valid -> data_valid == 0;}
constraint latch_data { !prev_data_valid -> data == prev_data;}
endclass
This works assuming you call randomize() once per clock cycle.
OK, I was able to solve my first problem. But still can not figure out how to generate random valid signal which will stay high one clock cycle only. Any tips would be appreciated.

VHDL signal dimension issue when reducing a generic value down to 0

How can one handle this case:
entity foo is
generic (
num_instances : natural := 8
);
port (
data_in_per_instance : in std_logic_vector(num_instances-1 downto 0);
data_out_per_instance : out std_logic_vector(num_instances-1 downto 0)
);
end foo;
architecture bar of foo is
component do_stuff is
port(
din : in std_logic;
dout : out std_logic
);
end component do_stuff;
signal sig_per_instance : std_logic_vector(num_instances-1 downto 0);
begin
L1: for i in 0 to num_instances-1 generate
L2: do_stuff
port map(
din => data_in_per_instance(i),
dout => data_out_per_instance(i)
);
end generate;
end bar;
The problem here is that if num_instances is reduced to 0 there will be an error when the signal ranges (num_instances-1 downto 0) are evaluated....
Is there an elegant way around this? All I can come up with is using a function like max(num_instances-1,0) to prevent this problem (but then synthesis may not give me exactly what I want, i.e. nothing).
Is there some way to handle this case a little more seamless?
A simple answer is to wrap the for-generate statement in an if-generate, if num_instances /= 0 generate ... Unfortunately if-generates have no else part, however there is nothing to stop you adding a second if num_instances = 0 generate ... statement to handle that special case.
Alternatively you can wrap the problem part of the for-generate using if-generate.
EDIT: re the need for a correct signal declaration guarded by the if ... generate.
AHA! You may have discovered a legitimate use for VHDL's (in my experience) rarely used "block" statement!
A block statement may contain signal declarations, and can be wrapped in a generate.
So this is valid VHDL:
Normality : block is
-- signal declarations here
begin
-- concurrent code here
end block Normality;
and it can be legally wrapped in a generate statement...
A std_logic_vector with an empty range (for example 3 downto 4) is perfectly legitimate - it's called a "null range" by the LRM. If you create one, then (at least with Modelsim) you will get warnings, which is usually considered poor form. To eliminate those, then Brian's block suggestion is what you'll have do.
Similarly the for..generate will result in an empty loop and no instances. No warnings for this.
I'm intrigued why you'd want a block with no instances in? I'd make num_instances a positive to force at least one of them, but that may not actually what you want!

Counter with push button switch design using VHDL and Xilinx

I'm very new to VHDL and XILINX ISE. I use the version 13.2 for Xilinx ISE.
I want to design a very simple counter with the following inputs:
Direction
Count
The count input will be assigned to a button and I want the counter to count up or down according to direction input when the button is pressed. I have written a sample VHDL before this one. It had a clock input and It was counting according to the clock input. Now I want it to count when I press the button instead of counting synchronously.
Here's my VHDL code (please tell me if my code have a logical or any other flaw):
entity counter is
Port ( COUNT_EN : in STD_LOGIC;
DIRECTION : in STD_LOGIC;
COUNT_OUT : out STD_LOGIC_VECTOR (3 downto 0));
end counter;
architecture Behavioral of counter is
signal count_int : std_logic_vector(3 downto 0) := "0000";
begin
process
begin
if COUNT_EN='1' then
if DIRECTION='1' then
count_int <= count_int + 1;
else
count_int <= count_int - 1;
end if;
end if;
end process;
COUNT_OUT <= count_int;
end Behavioral;
I use Spartan xc3s500e and I placed the inputs accordingly. Below is my .ucf file:
#Created by Constraints Editor (xc3s500e-fg320-5) - 2013/03/18
NET "COUNT_EN" LOC = K17;
NET "COUNT_OUT[0]" LOC = F12;
NET "COUNT_OUT[1]" LOC = E12;
NET "COUNT_OUT[2]" LOC = E11;
NET "COUNT_OUT[3]" LOC = F11;
NET "DIRECTION" LOC = L13;
#Created by Constraints Editor (xc3s500e-fg320-5) - 2013/03/18
NET "COUNT_EN" CLOCK_DEDICATED_ROUTE = FALSE;
I needed to change the last line because I was getting the error:
This will not allow the use of the fast path between the IO and the Clock...
After having this error gone, I programmed the device. But the output (leds) acted crazy. They sometimes stood still for a few seconds, sometimes just flashed very fast. I could not figure out where my mistake is. I would appreciate any help, some beginner tutorials are greatly appreciated (the links i found directed me to xilinx's documentations and they seemed quite complicated for a beginner).
From your description I understand that you are not looking for an Asynchronous Counter.
What you need is counter that counts on trigger from PushButton Switch. The below RTL should work:
If any difficulty in HDL coding let me know.
You don't have a clock. Once the COUNT_EN and DIRECTION conditions are satisfied, the count_int variable is going to increase as fast as it possibly can... in fact the timing of when individual bits change will probably make the entire thing completely unstable and incorrect.
You should always use a clock... just to allow the FPGA to get the timing right.
In this case, put the clock back... then add a new signal COUNT_EN_LAST. Save the old COUNT_EN each pass through the clocked process. Only increment when COUNT_EN = '1' and COUNT_EN_LAST = '0'.
In fact, you'll next find that you need to "debounce" the input. Physical buttons/switches "bounce" and give you multiple off-on events per single button press. For that, you'd simply make COUNT_EN_LAST a vector (say 5 long), shift new values into it each time ("COUNT_EN_LAST <= COUNT_EN_LAST(3 downto 0) & COUNT_EN;"), and only increment when COUNT_EN_LAST = "01111", or right before they're all 1's. The length of the vector you need will change depending on how fast your clock is and how long the switch can bounce before settling down to the new state.

Resources