- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello I'm Alex and I am novice for VHDL coding. if my english awful pls forgive me.
I trying to understand VHDL PROCESS statement. I try with 1bit full adder with carry save function in Quartus2 v15. I write down code:LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
-- truth-table of full-adder
-- with three inputs: ci{carry_in}, a{first in} and b{second in}
-- and two ouputs: s{sum} and co{carry_out}
-- ci a b | s co
-- -----------------
-- 0 0 0 | 0 0
-- 0 0 1 | 1 0
-- 0 1 0 | 1 0
-- 0 1 1 | 0 1
-- 1 0 0 | 1 0
-- 1 0 1 | 0 1
-- 1 1 0 | 0 1
-- 1 1 1 | 1 1
ENTITY full_add_1bit IS
PORT (
ci : IN STD_LOGIC;
a : IN STD_LOGIC;
b : IN STD_LOGIC;
s : OUT STD_LOGIC;
co : OUT STD_LOGIC
);
END full_add_1bit;
ARCHITECTURE b OF full_add_1bit IS
BEGIN
p0 : PROCESS(ci, a, b)
VARIABLE
aab,
aob,
axb,
sxc : STD_LOGIC;
BEGIN
aab := a AND b;
axb := a XOR b;
sxc := axb XOR ci;
s <= sxc;
IF ci = '0' THEN
co <= aab;
ELSIF ci = '1' THEN
aob := axb XOR aab; -- the same as (a OR b)
co <= aob;
END IF;
END PROCESS p0;
END b;
but during compilation i recieves message --- Quote Start --- Warning (10631): VHDL Process Statement warning at full_add_1bit.vhd(30): inferring latch(es) for signal or variable "co", which holds its previous value in one or more paths through the process --- Quote End --- I follow the simple logic - let's compute new values then do all signal assignments and the question is question1 : does pressure on variables so need?! I rewrite architecture to new one, let's compiler do all work: ARCHITECTURE b1 OF full_add_1bit IS
BEGIN
p0 : PROCESS(ci, a, b)
VARIABLE
result_i : INTEGER;
VARIABLE
result_v : STD_LOGIC_VECTOR (0 TO 1);
BEGIN
result_i := CONV_INTEGER(a)+CONV_INTEGER(b)+CONV_INTEGER(ci);
result_v := CONV_STD_LOGIC_VECTOR (result_i, 2);
co <= result_v(0);
s <= result_v(1);
END PROCESS p0;
END b1;
Finally i make schematic for this with 2mux1 blocks as for fun... in the attachments. never use schematic for establishing any equation - you waste your time. But result is the same with that scheme. question 2: how to find the way to good coding style?
Link Copied
- « Previous
-
- 1
- 2
- Next »
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have two examples of code for two registers writing from one bus. Which example is more suitable?
the first implementation reg_n : process(r, clk, wrn)
variable t : unsigned(n'range);
begin
if r = '1' then
t := to_unsigned(0, t'length);
elsif rising_edge(clk) then
if wrn = '1' then
t := resize(d, t'length);
end if;
end if;
n <= t;
end process reg_n;
reg_k : process(r, clk, wrk, wrn)
variable t : unsigned(k'range);
begin
if r = '1' then
t := to_unsigned(0, t'length);
elsif rising_edge(clk) then
if wrk = '1' and wrn = '0' then
t := resize(d, t'length);
end if;
end if;
k <= t;
end process reg_k;
and the second implementaion reg_n : process(r, wrn, wrk)
variable t : unsigned(n'range);
begin
if r = '1' then
t := to_unsigned(0, t'length);
elsif rising_edge(wrn) then
if wrk = '0' then
t := resize(d, t'length);
end if;
end if;
n <= t;
end process reg_n;
reg_k : process(r, wrk, wrn)
variable t : unsigned(k'range);
begin
if r = '1' then
t := to_unsigned(0, t'length);
elsif rising_edge(wrk) then
if wrn = '0' then
t := resize(d, t'length);
end if;
end if;
k <= t;
end process reg_k;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Neither. Why bother using variables at all. You could just sign directly to k or n? Also the codes are not functionally equivalent so you cannot compare them.
Also, assigning signals outside the clocked part or the code is not a recommended style.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
okay . the second is very bad . You should await that signals comes like clocks - nonsense.
what for the first style, your should capture Enable signal before clock transtion or signal should be stable for clock-period. or must i put multiplexor on data-in? Why I bother vaiables? I follow examples that books and web provide. <- it is common convention :) It seems that i 've alraedy asked similar question. I don't remember where...- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If the examples you are looking at look anything like your code above, I highly suggest you ditch those as very poor examples. There is hardly ever a situation where a variable is required in synthesisable logic. Variables can have issues of you use them wrong that you don't get with signals. Variables are best avoided.
I can't comment on the code about whether you need mixing our anything. I have no idea on the specs of the design. But you should try and register all outputs.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The sensitivity list for a clocked process should only contain the clock and the reset signals. If you add the wrn and wrk signals to the list, you will create a design that will behave differently in a simulator and on a real FPGA. Quartus will ignore your sensitivity list and just synthesize as if it was (r, clk) so if you want to simulate it correctly in Modelsim you should write it as is in your code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- The sensitivity list for a clocked process should only contain the clock and the reset signals. If you add the wrn and wrk signals to the list, you will create a design that will behave differently in a simulator and on a real FPGA. Quartus will ignore your sensitivity list and just synthesize as if it was (r, clk) so if you want to simulate it correctly in Modelsim you should write it as is in your code. --- Quote End --- If it is a synchronous process, and you add all the signals in the file, it will still behave like a synchronous process, and will still synthesise to a synchronous process, and the synthed design and the simulation will match. All adding all the extra signals does is cause the simulator to trigger the process when any of the signals changes. But because stuff doesnt actually happen unless there is a rising edge of the clock, nothing actually changes inside the process. So all you do is add extra work for the simulator to do to action the process when nothing actually happens inside the process.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- The sensitivity list for a clocked process should only contain the clock and the reset signals. If you add the wrn and wrk signals to the list, you will create a design that will behave differently in a simulator and on a real FPGA. Quartus will ignore your sensitivity list and just synthesize as if it was (r, clk) so if you want to simulate it correctly in Modelsim you should write it as is in your code. --- Quote End --- I have tried to remove one and with standard option set the quartus reports me that i should include them in process-sensitivity list xD and if you want trully asyncronus modeling -> let's enter the process, stop it through breakpoint in statements for clock transition, then manually change signal 'r' value to one that send command reset to your schematic. and wait when the reset occur . will we have glitch?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How about such cutting for sensitivity list when describing FSM? I know that is very badexample with impure function instead of process but ... quartus eats it up.
library ieee;
use ieee.std_logic_1164.all;
entity fsm is
port(
clk,
enable_SM,
start,
pk_eq_k,
pn_eq_n : IN std_logic;
pk0,
pkp1,
pn0,
pnp1 : OUT std_logic
);
end fsm;
architecture v1 of fsm is
type state_type is (s1, s2, s3, s4);
impure function next_state(st : state_type) return state_type is
begin
case st is
when s1 =>
if start= '1' then
return s2;
else
return s1;
end if;
when s2 =>
return s3;
when s3 =>
if pk_eq_k = '0' then
return s3;
else
return s4;
end if;
when s4 =>
if pn_eq_n = '0' then
return s4;
else
return s2;
end if;
end case;
end next_state;
signal
st : state_type;
begin
process(enable_SM, clk)
begin
if enable_SM = '0' then
st <= s1;
elsif rising_edge(clk) then
st <= next_state(st);
end if;
end process;
pk0 <= '1' when (st = s1 or (st = s4 and pk_eq_k = '1')) else '0';
pkp1 <= '1' when st = s3 else '0';
pn0 <= '1' when st = s2 else '0';
pnp1 <= '1' when st = s4 else '0';
end v1;
The code above ... struck me so / really assignment to signal operators imply implicit processes . so i change a little bit behaviour to fsm architecture v2 of fsm is
type state_type is (s1, s2, s3, s4);
signal st : state_type;
procedure state_transition is
begin
case st is
when s1 =>
if start= '1' then
pk0 <= '1';
st <= s2;
else
pk0 <= '0';
st <= s1;
end if;
pkp1 <= '0';
pn0 <= '0';
pnp1 <= '0';
when s2 =>
pn0 <= '1';
pkp1 <= '1';
pk0 <= '0';
pnp1 <= '0';
st <= s3;
when s3 =>
if pk_eq_k = '0' then
pk0 <= '0';
pkp1 <= '1';
pnp1 <= '0';
st <= s3;
else
pk0 <= '1';
pkp1 <= '0';
pnp1 <= '1';
st <= s4;
end if;
pn0 <= '0';
when s4 =>
if pn_eq_n = '0' then
pnp1 <= '1';
st <= s4;
else
pnp1 <= '0';
st <= s2;
end if;
pkp1 <= '0';
pn0 <= '0';
pk0 <= '0';
end case;
end state_transition;
begin
process(enable_SM_n, clk)
begin
if enable_SM_n = '1' then
st <= s1;
pn0 <= '0';
pkp1 <= '0';
pk0 <= '0';
pnp1 <= '0';
elsif rising_edge(clk) then
state_transition;
end if;
end process;
end v2;
but all is fine until you you catch multiple assignments. by the way ... (why my rang became as written? is it joke?)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I dont understand the questions, both processes and code examples imply synchronous code. But the first example as asynchronous outputs while the 2nd is all registered outputs...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tricky , you shed the light for me. seriously.
the both state machines are Melay machine. I know a lot of about state machines from theory. it is better to follow style with two separate processes for describing fsm. so model and synthesis will be similar. be aware : you can get unexpected clock-enable pins instead of asynchronus reset with styles as above.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yes - you get that because you didnt reset all output in the async reset branch.
The prefered style for state machines now is a single clocked process. This avoids any latch creation and can be easier to track. The two process style is a throwback to very old synthesis engines that required separated logic and register processes. And so many textbooks taught this style. Now there is no restriction there is no need to separate logic and registers.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
-
- 1
- 2
- Next »