Modifying an input port - Page 1
Forum section: electronics / general

author: mn
author_rank: Contributor
timestamp: September 11, 2017, 01:19:39 pm
content: HiThe question may look so simple, but I appreciate if someone explain that. I want to read a register (std_logic_vector) and modify it, e.g. shift it to left or right. If I defineCode:port (a: in std_logic_vector(3 downto 0));then I am not able to modify it since it can not be written. So, what should i do? If I define a signal to hold a copy of that like thisCode:signal tmp:std_logic_vector(3 downto 0) := a;then, is that a valid statement for synthesis? Is there any better option?

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: September 14, 2017, 11:50:33 am
content: Quote from: mn on September 11, 2017, 01:19:39 pmYou can't modify the input itself because it is coming from outside the entity. What you can do is:-1. feed it through some combinational logic to produce an output which is related to it, eg. shifted left or right.2. Load it into a register and then shift it left or right.Which approach you would use depends on the nature of the 'modification'. If you want the output to always be a shifted version of the current input then use combinatorial logic. If you want to progressively shift the data on each clock then use a register.QuoteYou can't do that. The ':=' operator is only for giving the signal a default initial value (which is ignored in synthesis).A signal is the equivalent of a wire. There is no point copying an input directly into a signal because the input is already a signal, so all you have done is joined a wire onto another wire. But if you put some logic between them then you can do something useful. For example:-Code:entity shifter isPort (a: in std_logic_vector(3 downto 0);b: out std_logic_vector(3 downto 0));end shifter;architecture Behavioural of shifter isbeginb <= a(2 downto 0) & '0';end BehavioralThis takes the lower 3 bits of a, adds a '0' at the right-hand end, then sends the resulting 4 bit vector to output b, effectively shifting the input left. This technique can be used to shift or rotate by any number of places. You could also add a vector to control how many places to shift, and then you have a programmable barrel shifter.If you want to store the data in a register for subsequent manipulation then you need to clock it. The code below adds inputs 'clk' and 'load' to clock the register and select between loading and shifting. When load is 1, port input a is clocked into the register. When load is 0, the register's output is shifted and clocked back into itself. Finally, the register's output is routed to port output b.Code:entity shiftreg isPort (clk: in std_logic;load: in std_logic;a: in std_logic_vector(3 downto 0);b: out std_logic_vector(3 downto 0));end shiftreg;architecture Behavioural of shiftreg issignal reg: std_logic_vector(3 downto 0);beginprocess (clk, reg)beginif rising_edge(clk) thenif (load='1') thenreg <= a;elsereg <= reg(2 downto 0) & '0';end if;end if;end process;b <= reg;end Behavioral;You might wonder why we have to create a signal for the register, rather than just clocking b. The reason is that b isoutputonly, so we cannot read it. However if we make it inout then we can:-Code:port ( b: inout std_logic_vector(3 downto 0)...process (clk)beginif rising_edge(clk) thenif (load='1') thenb <= a;elseb <= b(2 downto 0) & '0';end if;end if;end process;In practice both versions may produce identical logic, so (apart from extra typing) there is no penalty for using the intermediate signal - and it makes the intention clearer.