Mathematical operations within function argument - function

Is it possible to perform mathematical operations within the argument when calling a function?
For example:
answer = to_integer(dividend/divisor);

While Phillipe exaggerates the efficiency of the average VHDL coder, it's not a difficult thing to try.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
end entity;
architecture fum of foo is
signal dividend: unsigned (7 downto 0) := ("11111111"); -- 255
signal divisor: unsigned (7 downto 0) := ("00001111"); -- 15
signal answer: integer;
begin
process
begin
answer <= to_integer(dividend/divisor);
wait for 0 ns;
report "answer = " & integer'image(answer);
wait;
end process;
end architecture;
The result:
foo.vhdl:17:9:#0ns:(report note): answer = 17
The wait for 0 ns; allows answer to assume the value of the operation (it's a signal, and assignments don't occur when any process is executing or has not yet suspended). For 0 ns will cause a delta cycle delay.
If answer were a variable declared in the process it's value would be available immediately and the wait wouldn't be necessary.
The last wait statement without a delay prevents the process from executing repeatedly.

Related

Xilinx VHDL latch warning troubleshooting

Xilinx is inferring a latch for a VHDL code i've written. I've looked up the possible causes for this and found that it's often due to incomplete if or case statements. I've gone through and made sure to include else and when others statements, but i'm still receiving the warning. I believe this is also affecting another project i'm working on so i'd like to understand why this is the case.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity state_machine is
port(trig, en: in std_logic; cstate,nstate: out std_logic_vector(0 to 2));
end state_machine;
architecture Behavioral of state_machine is
signal cstate_s,nstate_s: std_logic_vector(0 to 2);
begin
cstate <= cstate_s;
nstate <= nstate_s;
process(en, cstate_s)
begin
if en = '1' then
nstate_s <= "111";
if cstate_s = "111" then
nstate_s <= "011";
elsif cstate_s = "011" then
nstate_s <= "100";
elsif cstate_s = "100" then
nstate_s <= "101";
elsif cstate_s = "101" then
nstate_s <= "110";
elsif cstate_s = "110" then
nstate_s <= "111";
else
null;
end if;
else
null;
end if;
end process;
process(trig, nstate_s)
begin
if rising_edge(trig) then
cstate_s <= nstate_s;
else
null;
end if;
end process;
end Behavioral;
WARNING:Xst:737 - Found 3-bit latch for signal . Latches may
be generated from incomplete case or if statements. We do not
recommend the use of latches in FPGA/CPLD designs, as they may lead to
timing problems.
For there to be no latches synthesised when a combinational process is synthesised, there must be no path between begin and end process; where all the outputs of the process are not assigned. This is called complete assignment. An output of the process is any signal assigned anywhere within it.
You have such paths. When any path with your null statements are executed, the output of your first process (nstate_s) is not assigned to. Therefore, you will get latches synthesised. There is no point in just having a null statement. If you genuinely don't care what value is assigned to your outputs in these paths, assign the outputs to '-', which means don't care in VHDL.
By the way (assuming trig is a clock), your second process is not combinational (it is sequential) and so you don't need to obey complete assignment; your else branch is unnecessary.

Memory allocation in Julia function

Here is a simple function in Julia 0.5.
function foo{T<:AbstractFloat}(x::T)
a = zero(T)
b = zero(T)
return x
end
I started with julia --track-allocation=user. then include("test.jl"). test.jl only has this function. Run foo(5.). Then Profile.clear_malloc_data(). foo(5.) again in the REPL. Quit julia. Look at the file test.jl.mem.
- function foo{T<:AbstractFloat}(x::T)
- a = zero(T)
194973 b = zero(T)
0 return x
- end
-
Why is there 194973 bytes of memory allocated here? This is also not the first line of the function. Although after Profile.clear_malloc_data(), this shouldn't matter.
Let's clarify some parts of the relevant documentation, which can be a little misleading:
In interpreting the results, there are a few important details. Under the user setting, the first line of any function directly called from the REPL will exhibit allocation due to events that happen in the REPL code itself.
Indeed, the line with allocation is not the first line. However, it is still the first tracked line, since Julia 0.5 has some issues with tracking allocation on the actual first statement (this has been fixed on v0.6). Note that it may also (contrary to what the documentation says) propagate into functions, even if they are annotated with #noinline. The only real solution is to ensure the first statement of what's being called is something you don't want to measure.
More significantly, JIT-compilation also adds to allocation counts, because much of Julia’s compiler is written in Julia (and compilation usually requires memory allocation). The recommended procedure is to force compilation by executing all the commands you want to analyze, then call Profile.clear_malloc_data() to reset all allocation counters. Finally, execute the desired commands and quit Julia to trigger the generation of the .mem files.
You're right that Profile.clear_malloc_data() prevents the allocation for JIT compilation being counted. However, this paragraph is separate from the first paragraph; clear_malloc_data does not do anything about allocation due to "events that happen in the REPL code itself".
Indeed, as I'm sure you suspected, there is no allocation in this function:
julia> function foo{T<:AbstractFloat}(x::T)
a = zero(T)
b = zero(T)
return x
end
foo (generic function with 1 method)
julia> #allocated foo(5.)
0
The numbers you see are due to events in the REPL itself. To avoid this issue, wrap the code to measure in a function. That is to say, we can use this as our test harness, perhaps after disabling inlining on foo with #noinline. For instance, here's a revised test.jl:
#noinline function foo{T<:AbstractFloat}(x::T)
a = zero(T)
b = zero(T)
return x
end
function do_measurements()
x = 0. # dummy statement
x += foo(5.)
x # prevent foo call being optimized out
# (it won't, but this is good practice)
end
Then a REPL session:
julia> include("test.jl")
do_measurements (generic function with 1 method)
julia> do_measurements()
5.0
julia> Profile.clear_malloc_data()
julia> do_measurements()
5.0
Which produces the expected result:
- #noinline function foo{T<:AbstractFloat}(x::T)
0 a = zero(T)
0 b = zero(T)
0 return x
- end
-
- function do_measurements()
155351 x = 0. # dummy statement
0 x += foo(5.)
0 x # prevent foo call being optimized out
- # (it won't, but this is good practice)
- end
-

FPGA output pins outputting wrong state

I am writing a LCD controller for an FPGA and am having a really weird (for me at least) problem. The state machine that's supposed to output the needed bits to the screen misbehaves and gets the output pins "stuck" in an old state, while it clearly has moved on to later states.
Here is the relevant parts of the state machine:
PROCESS (clk)
VARIABLE count: INTEGER RANGE 0 TO clk_divider; -- clk_divider is a generic positive.
BEGIN
IF (clk'EVENT AND clk = '1') THEN
count := count + 1;
IF (count = clk_divider) THEN
EAUX <= NOT EAUX;
count := 0;
END IF;
END IF;
END PROCESS;
....
PROCESS (EAUX)
BEGIN
IF (EAUX'EVENT AND EAUX = '1') THEN
pr_state <= nx_state;
END IF;
END PROCESS;
....
PROCESS (pr_state)
BEGIN
CASE pr_state IS
WHEN EntryMode => --6=1,7=Cursor increment/decrement, 8=Display shift on/off
RSs <='0';
DB(7 DOWNTO 0) := "00000110";
nx_state <= WriteData;
WHEN WriteData => --Write data to LCD:
RSs <='1';
YLED <= '1';
DB(7 DOWNTO 0) := "01011111";
i := i + 1;
IF (i < chars) THEN
nx_state <= WriteData;
ELSE
i := 0;
nx_state <= ReturnHome;
END IF;
WHEN ReturnHome => --Return cursor
RSs <='0';
YLED <= '1';
DB(7 DOWNTO 0) := "01011111";
nx_state <= WriteData;
END CASE;
END PROCESS;
Where the bits in the variable DB is assigned to the signal DBOUT:
DBOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) -- In entity
SHARED VARIABLE DB : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000"; -- In Architecture
DBOUT <= DB;
DBOUT is outputted (in the .ucf-file) as:
NET "DBOUT(0)" LOC = P10;
NET "DBOUT(1)" LOC = P11;
NET "DBOUT(2)" LOC = P12;
NET "DBOUT(3)" LOC = P13;
NET "DBOUT(4)" LOC = P15;
NET "DBOUT(5)" LOC = P16;
NET "DBOUT(6)" LOC = P18;
NET "DBOUT(7)" LOC = P19;
Using an oscilloscope on the pins I can see that it is clearly stuck outputting the "EntryMode" bits and the "RSs" is set at low, while the YLED (the internal led on the FPGA) is on (it's off at all other states). The really weird thing is (and this took a real long time to find) is that if I change the EntryMode bits from
"00000110"
to
"00000100"
it successfully passes the state and outputs the correct bits. It might be true for other changes as well, but I don't really feel like testing that too much. Any help or tips would be highly appreciated!
UPDATE:
After popular request I explicitly put YLED to low in all the early states and switched (back) DB to be a signal. The result is that I can't reach the later states at all, or at least stay in them (even when fiddling with the magic bits, which I guess is a good thing) as the YLED only stays on for a split second after booting the FPGA.
There is a complete example, including theory, state machine, and VHDL code on pages 279-290 of "Finite State Machines in Hardware: Theory and Design...", by Volnei Pedroni, MIT Press, Dec. 2013.

VHDL: std logic vector not holding value between process calls

I have the following code snippet:
SIGNAL ALU_hilo : STD_LOGIC_VECTOR(63 downto 0);
PROCESS ( ALU_ctl, Ainput, Binput )
BEGIN
-- Select ALU operation
CASE ALU_ctl IS
-- ALU performs ALUresult = A_input AND B_input
WHEN "0000" => ALU_Internal <= Ainput AND Binput;
-- ALU performs ALUresult = A_input OR B_input
WHEN "0001" => ALU_Internal <= Ainput OR Binput;
-- ALU performs ALUresult = A_input + B_input
WHEN "0010" => ALU_Internal <= Ainput + Binput;
-- ALU performs ?
WHEN "0011" => ALU_Internal <= X"00000000";
-- ALU performs ?
WHEN "0100" => ALU_Internal <= X"00000000";
-- ALU performs ?
WHEN "0101" => ALU_Internal <= X"00000000";
-- ALU performs ALUresult = A_input - B_input
WHEN "0110" => ALU_Internal <= Ainput - Binput;
-- ALU performs SLT
WHEN "0111" => ALU_Internal <= Ainput - Binput ;
-- ALU performs MFHI
WHEN "1101" => ALU_Internal <= ALU_hilo(63 downto 32);
-- ALU performs MFLO
WHEN "1100" => ALU_Internal <= ALU_hilo(31 downto 0);
-- ALU performs MULT
when "1000" => ALU_hilo <= Ainput * Binput;
WHEN "1001" => ALU_Internal <= Binput(15 downto 0) & X"0000";
WHEN OTHERS => ALU_Internal <= X"00000000";
END CASE;
END PROCESS;
All of the other signals here are declared previously and work fine. My problem is that ALU_hilo is being overwritten with 0x0 on subsequent process calls where ALU_ctl is not "1000". How can I fix this so that ALU_hilo holds its value unless ALU_ctl is 1000?
You're creating latches for signals that are only assigned for specific conditions of one of the signals in the sensitivity list.
You're more than likely seeing an event on Ainput or Binput (or both) while ALU_ctl is still "1000".
Without controlling when you enable latches specifically, this process may not synthesize to your intended function. If you intend to create latches here you should use an enable that's only valid when all other signals used in the process are unchanging.
You could similarly us a clock edge and create registers instead of latches where ALU_ctl serves as an address to select which register is updated. It would imply that Ainput and Binput occur on the same clock.
(And processes aren't called, their execution is resumed when one of their sensitivity list elements has an event. There's an implied wait on ALU_ctl, Ainput, Binput; as the last statement of the process. A process is a sequence of statements that will repeat unless stopped.)

initial block delaying in verilog

When implementing a single cycle mips in Verilog. PC is initialized to address 0
then updates its value to PC+1 at the posedge of the clock which was also initialized to 0.
The problem is in simulation, the instruction at address 0 takes only half clock cycle then the PC increments by 4 and then the second instruction enters the processor.
simulation screenshot http://imagizer.imageshack.us/v2/800x600q90/36/0cxn.jpg
Neither initializing clock by 1 nor adding delays before initializing PC solved the problem
this is my clock module
`timescale 1ps / 1ps
module clk_gen( clk );
output reg clk ;
initial begin
clk<=0;
end
always begin
#1400 clk=!clk;
end
endmodule
PC module:
module PC(inPC, Address, clk);
input [31:0] inPC;
input clk;
output reg [31:0] Address;
initial begin
Address=32'd0;
end
always #( posedge clk) begin
Address <= inPC;
end
endmodule
The question does not seem to relate to your clock module but based on that code.
Assuming you are not expect this to be synthesisable. Idealy you defined a reg or logic value in one process.
NB if your simulator supports it I would define times with absolutes ie #1.4ns for your delay.
initial begin
clk <= 1'b0;
forever begin
#1.4ns clk <= ~clk ;
end
end