Altera Quartus and modelsim - processor

I am writing something in verilog in quartus, and appeared to me something strange, but pretty simple actually
This code increments the address correctly
module counter(
input wire clock,
input wire reset,
output reg [4:0]address
);
initial
begin
address = 5'b0
end
always#(posedge clock)
begin
if(reset)
begin
address <= 5'b0;
end
else
begin
address <= address + 5'b00001;
end
end
endmodule
this, the bits that change become not matter, it happens when I start the output to something other than 0
module counter(
input wire clock,
input wire reset,
output reg [4:0]address
);
initial
begin
address = 5'b11101;
end
always#(posedge clock)
begin
if(reset)
begin
address <= 5'b0;
end
else
begin
address <= address + 5'b00001;
end
end
endmodule
Does anyone know any way to solve this problem?

While it is difficult to tell exactly what you are saying, it seems you are curious as to why changing the starting value in the initial block seems to have no affect on where the counter starts.
It seems you are likely performing a reset as part of your testbench, so when you look at address, the value always starts at 0 (because the initial block setting is changed by the reset in the always block).

This part is suspicious to me:
if(reset)
begin
address <= 5'b0;
end
Should be:
if(reset)
begin
address <= 5'b00000;
end
You can try use this implementation with load and start signal:
module Counter(load,clk,start,data_in,data_out);
input load;
input clk;
input start;
input [5-1:0] data_in;
output [5-1:0] data_out;
reg [5-1:0] tmp;
initial
begin
tmp = 5'b0000;
end
always # ( posedge clk)
begin
if(~start)
begin
tmp <= 5'b0000;
end
else if(load)
tmp <= data_in;
else
tmp <= tmp + 1'b1;
end
assign data_out = tmp;
endmodule

Related

verilog bit select of concatenation

module mac #(
parameter integer A_BITWIDTH = 8,
parameter integer B_BITWIDTH = A_BITWIDTH,
parameter integer OUT_BITWIDTH = 20,
parameter integer C_BITWIDTH = OUT_BITWIDTH - 1
)
(
input clk,
input rstn,
input en,
input add,
input [A_BITWIDTH-1:0] data_a,
input [B_BITWIDTH-1:0] data_b,
input [C_BITWIDTH-1:0] data_c,
output reg done,
output [OUT_BITWIDTH-1:0] out
);
localparam
STATE_IDLE = 2'b00,
STATE_MULT = 2'b01,
STATE_ACCM = 2'b10;
reg [1:0] state;
reg signed [OUT_BITWIDTH-1:0] out_temp;
reg signed [A_BITWIDTH-1:0] data_a_bf;
reg signed [B_BITWIDTH-1:0] data_b_bf;
reg signed [C_BITWIDTH-1:0] data_c_bf;
assign out = out_temp;
always # (posedge clk or negedge rstn) begin
if(!rstn) begin
state <= STATE_IDLE;
data_a_bf <= {A_BITWIDTH{1'b0}};
data_b_bf <= {B_BITWIDTH{1'b0}};
data_c_bf <= {C_BITWIDTH{1'b0}};
done <= 1'b0;
out_temp <={OUT_BITWIDTH{1'b0}};
end
else begin
case(state)
STATE_IDLE: begin
// TO DO
// Done flag reset!
data_a_bf <= {A_BITWIDTH{1'b0}};
data_b_bf <= {B_BITWIDTH{1'b0}};
data_c_bf <= {C_BITWIDTH{1'b0}};
out_temp <={OUT_BITWIDTH{1'b0}};
done <= 1'b0;
if(en && !done) begin
// If en == 1 and done != 1, then running state.
// And capture data_a, data_b, data_c to buffer
data_a_bf <= data_a;
data_b_bf <= data_b;
data_c_bf <= data_c;
state <= STATE_MULT;
end
else begin
// If not, just waiting for condition.
end
end
STATE_MULT: begin
// TO DO;
if (!add) begin
// If add signal is low, do muliply with data_a_bf and data_b_bf.
//out_temp <= data_a_bf * data_b_bf;
out_temp <= {{{A_BITWIDTH{data_a_bf[7]}}, data_a_bf}*{{B_BITWIDTH{data_b_bf[7]}}, data_b_bf}}[15:0]; // >> this invokes a error, which is syntax error near "["
end
else begin
// If add signal is high, shift data_a_bf to match bit representation.
//out_temp <= {data_a_bf, 8'b0};
out_temp <= {data_a_bf, 8'b0};
end
state <= STATE_ACCM;
end
STATE_ACCM: begin
// TO DO
// Do add and make output 'done' flag high.( done = 1)
out_temp <= out_temp + data_c_bf;
done <= 1'b1;
state <= STATE_IDLE;
end
default:;
endcase
end
end
endmodule
I want to do 'bit select' concatenation of data_a_bf signed extension * data_b_bf signed extension and assign it to out_temp, but it occurs a syntax error. How can I do this?
I don't know how to do bit select of it.
I think you just need to see error line.
I just upload all code.
Selecting a bit of a concatenation is a feature of SystemVerilog, not Verilog. Make sure your file has a .sv file extension. The tool that you are using might also have a switch to turn on support for SystemVerilog.
A Verilog friendly solution would be to create a bit mask.
For example, change:
out_temp <= {{{A_BITWIDTH{data_a_bf[7]}}, data_a_bf}*{{B_BITWIDTH{data_b_bf[7]}}, data_b_bf}}[15:0]; // >> this invokes a error, which is syntax error near "["
To:
out_temp <= {{{A_BITWIDTH{data_a_bf[7]}}, data_a_bf}*{{B_BITWIDTH{data_b_bf[7]}}, data_b_bf}} & 'h0FFFF;

i don't understand the utility of default values in state machine

I am trying to understand state machine in VHDL for detecting the edge on a signal in VHDL. in next state I dont understand why we put the:
"next_etat<= reg_etat" because I think it could work without any problem even without it .
I'd would what are the default value of reg_etat and next_etat when we have just run the program because their is no real default value like in c for example int var=0;
entity machine_etat is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
entree : in STD_LOGIC;
tc : out STD_LOGIC);
end machine_etat;
architecture architecture_machine_etat of machine_etat is
type T_etat is (idle,edge,one);
signal next_etat, reg_etat : T_etat;
begin
registre_etat: process(clk)
begin
if rising_edge(clk) then
if rst = ’1’ then
reg_etat <= idle;
else
reg_etat <= next_etat;
end if;
end if;
end process registre_etat;
tc <= ’1’ when reg_etat = edge else ’0’;
etat_suivant: process(reg_etat,entree)
begin
next_etat <= reg_etat;-- defaults values here i dont see their purpose
case reg_etat is
when idle =>
if entree =’1’ then
next_etat <= edge;
end if;
when edge =>
next_etat <= one;
when one =>
if entree =’0’ then
next_etat <= idle;
end if;
end case;
end process etat_suivant;
end architecture_machine_etat;
If you don't assign next_etat (pardon my French) in all situations, logical synthesis will infer a latch to remember it's state. A latch is something you don't want, as it is very sensitive to digital logic latencies and might become metastable: also something you don't want.
HDL programming significantly differs from CPU programming.

VHDL: button debounce inside a Mealy State Machine

Hi I'm trying to implement a mealy machine using VHDL, but I'll need to debounce the button press. My problem is I'm not sure where should I implement the debouncing. My current work is like this:
process(clk)
begin
if(clk' event and clk = '1') then
if rst = '1' then
curr_state <= state0;
else
curr_state <= next_state;
end if;
end if;
end process;
process(curr_state, op1,op0,rst) --here op1,op0 and rst are all physical buttons and I need to debounce op1 and op0
begin
if rst = '1' then
...some implementation
else
...implement the debounce logic first
...process some input
case curr_state is
when state0=>...implementation
...similar stuff
end case;
end process;
I'm not sure whether I'm doing in the right way or not. In the second process, should I put the rst processing like this, or should I put it inside when state0 block? Also, as the processing of debounce requires counting, do I put it outside the case block like this? Thank you!
I would use a completely separate block of code to debounce any button signals, allowing your state machine process to focus on just the state machine, without having to worry about anything else.
You could use a process like this to debounce the input. You could of course exchange variables for signals in this example (with associated assignment operator replacements).
process (clk)
constant DEBOUNCE_CLK_PERIODS : integer := 256; -- Or whatever provides enough debouncing
variable next_button_state : std_logic := '0'; -- Or whatever your 'unpressed' state is
variable debounce_count : integer range 0 to DEBOUNCE_CLK_PERIODS-1 := 0;
begin
if (rising_edge(clk)) then
if (bouncy_button_in /= next_button_state) then
next_button_state := bouncy_button_in;
debounce_count := 0;
else
if (debounce_count /= DEBOUNCE_CLK_PERIODS-1) then
debounce_count := debounce_count + 1;
else
debounced_button_out <= next_button_state;
end if;
end if;
end if;
end process;
Another option would be to sample the bouncy_button_in at a slow rate:
process (clk)
constant DEBOUNCE_CLK_DIVIDER : integer := 256;
variable debounce_count : integer range 0 to DEBOUNCE_CLK_DIVIDER-1 := 0;
begin
if (rising_edge(clk)) then
if (debounce_count /= DEBOUNCE_CLK_DIVIDER-1) then
debounce_count := debounce_count + 1;
else
debounce_count := 0;
debounced_button_out <= bouncy_button_in;
end if;
end if;
end process;
The advantage of the first method is that it will reject glitches in the input. In either case, you would use the debounced_button_out (or whatever you want to call it, perhaps rst) in your state machine, whose code then contains only the core state machine functionality.
If you wanted even more debouncing, you could use another counter to create an enable signal for the processes above, to effectively divide down the clock rate. This could be better than setting the division constant to a very high number, because you may not be able to meet timing if the counter gets beyond a certain size.
You could even create a debounce entity in a separate file, which could be instantiated for each button. It could have a generic for the constant in the above process.
There's also hardware debouncing, but I suppose that's outside the scope of this question.
In the second process, should I put the rst processing like this, or
should I put it inside when state0 block?
Only put it in the State0 block
Also, as the processing of
debounce requires counting, do I put it outside the case block like
this?
Counting needs to be done in a clocked process. Since you are doing a two process statemachine, you cannot do it in the case block. I typically put these sort of resources in a separate clocked process anyway.
For states, you need: IS_0, TO_1, IS_1, TO_0.
The TO_1 and TO_0 are your transition states. I transition from TO_1 to IS_1 when I see a 1 for 16 ms. I transition from TO_0 to IS_0 when I see a 0 for 16 ms. Run your counter when you are in the TO_1 or TO_0 state. Clear your counter when you are in the IS_1 or IS_0 state.
This should get you stated.

VHDL syntax issue

I'm getting an error during CheckSyntax for the following code I've tried. The error says:
"Line 48. parse error, unexpected VARIABLE Line 53. Undefined symbol 'InOutDetector'.
Line 57. InOutDetector: Undefined symbol (last report in this block)".
Can you let me know how should I fix this?
Here is an image of my code, as I could not paste it.
https://www.dropbox.com/s/ay8pjq4ojoep6ry/RoomLightController.png?dl=0
entity Room_Light_Controller is
port (
clk, sA, sB: IN STD_LOGIC;
sL: OUT STD_LOGIC
);
end Room_Light_Controller;
architecture Behavioral of Room_Light_Controller is
-- assuming sensors are variables sA and sB, and lights switch is sL
SIGNAL People : INTEGER:=0;
SIGNAL AllowNextCount : BIT:='0';
--unsigned int People=0; -- counter for people inside the room
--char AllowNextCount=0; -- boolean indicating if allowing next count or not
--short int InOutDetector; -- 1 = entering; -1 = exiting
begin
variable InOutDetectorDetector: integer;
process (clk)
begin
if ((sA = '0') and (sB = '1')) then
-- entering
InOutDetector := 1;
end if;
if ((sA = '1') and (sb = '0')) then
-- exiting
InOutDetector := -1;
end if;
if ((sA ='1') and (sB = '1') and (AllowNextCount = '1')) then
-- only when both sensors are touched validate the people counter
People := People+InOutDetector;
-- count once then block counting until the same person has finished entering/exiting
AllowNextCount <= '0';
end if;
if ((sA = '0') and (sB = '0')) then
-- it gets 0;0 only when someone has finished entering/exiting
-- pr at turn on; so now allow to counting again
AllowNextCount <= '1';
end if;
if (People > 0) then
sL <= '1'; -- Turn/keep lights on as long as People greater than 0
else
sL <= '0'; -- otherwise, turn them off
end if;
end process;
end Behavioral;
In addition to the error Amir notes that there is a name mismatch and the variable is declared in the wrong place, there is an additional error with the assignment to People:
library ieee;
use ieee.std_logic_1164.all;
entity Room_Light_Controller is
port (
clk, sA, sB: in std_logic;
sL: out std_logic
);
end entity Room_Light_Controller;
architecture Behavioral of Room_Light_Controller is
-- assuming sensors are variables sA and sB, and lights switch is sL
signal people: integer := 0;
signal allownextcount: bit := '0';
--unsigned int People=0; -- counter for people inside the room
--char AllowNextCount=0; -- boolean indicating if allowing next count or not
--short int InOutDetector; -- 1 = entering; -1 = exiting
begin
-- variable InOutDetectorDetector: integer;
process (clk)
variable InOutDetector: integer; -- as per Amir
begin
if sA = '0' and sB = '1' then
-- entering
InOutDetector := 1;
end if;
if sA = '1' and sb = '0' then
-- exiting
InOutDetector := -1;
end if;
if sA ='1' and sB = '1' and AllowNextCount = '1' then
-- only when both sensors are touched validate the people counter
People <= People + InOutDetector; -- was :=, signal assignment
-- count once then block counting until the same person has finished entering/exiting
AllowNextCount <= '0';
end if;
if sA = '0' and sB = '0' then
-- it gets 0;0 only when someone has finished entering/exiting
-- pr at turn on; so now allow to counting again
AllowNextCount <= '1';
end if;
if People > 0 then
sL <= '1'; -- Turn/keep lights on as long as People greater than 0
else
sL <= '0'; -- otherwise, turn them off
end if;
end process;
end architecture Behavioral;
People is a signal and requires the signal assignment symbol (<=) not the variable assignment symbol (:=).
After the two changes the VHDL design specification analyzes and elaborates.
Notice a context clause has been added to make your code a Minimal, Verifiable and Complete example.
Also note in the Help Center web page on Minimal, Complete, and Verifiable example the section Minimal and readable,
..Use consistent naming and indentation, and include comments if needed to explain portions of the code.
If this code were intended to be synthesize you might likely need to constrain the integers.
For execution efficiency all the independent if statements could be consolidated using elsif. That's hardly an issue in a small design, but the binary patterns described for sA and sB are mutually exclusive (while not exhaustive for type std_logic).
You neglected to provide the complete error messages, which appear to be output from XST. Historically the recommended design flow includes simulation, which if for no other purpose provides better syntax error messages from VHDL analysis.
XST historically assumes you are handing it a design description that is syntax error free, and is other wise quite sparse in providing adequate error messages.
The error message prefix (e.g. ERROR:HDLParsers:1209) can tell you how to find the problem via Xilinx's support site and/or documentation.
Declare the variable inside the process and rename it to (InOutDetector). You used (InOutDetector) inside the process.
Then if you want to run the process on clk rising edge, complete your process such as the following code :
process(clk)
variable InOutDetector : integer;
begin
if clk = '1' and clk'event then
-- your code
end if;
end process;
However if you don't want to use the clk rising edge, just complete the sensitivity list with parameters that you read or check it inside the process (sA,sB,AllowNextCount,People) and remove clk from the process sensitivity list.
Also be careful about incomplete if statements. Latches may be generated from incomplete case or if statements.

VHDL 'generate' FSM states

I have a variable number of modules linked to another module via a signal bus : std_logic_vector(NUM-1 downto 0), with each component using 8 bits, so that:
bus(7 downto 0) = first module
bus(15 downto 8) = second module
As for creating the instances and doing the port mapping, that is easily done with a
INST: for i in 0 to NUM-1 generate
Inst_module port map ( bus => bus(i*8+7 downto i*8) );
end generate INST;
My question:
I would like to be able to interface with each module via a FSM (since it needs to do some other things too), so would like to be able to 'generate' the following code, rather than having to write out each state manually (Where signal empty : std_logic_vector(NUM-1 downto 0) is a status flag for each module)
type state_type is (st0_idle, st1_work0, st1_work1 --,etc.)
signal state : state_type;
begin
process(empty)
begin
if RESET = '1' then
--reset FSM
state <= st0_idle;
else
if CLK'event and CLK='1' then
case state is
when st0_idle =>
if empty(0) = '0' then
state <= st1_work0;
elsif empty(1) = '1' then
state <= st1_work1;
--etc.
end if;
when st1_work0 =>
bus(7 downto 0) <= SOMETHING;
state <= st0_idle;
when st1_work1 =>
bus(15 downto 8) <= SOMETHINGELSE;
state <= st0_idle;
--etc..
end if;
end if;
end process;
As you can see, there is a lot of repetition. But I can't simply put a for-generate inside the case, so what should I do?
One good way to make processes with state machines more readable is to merge common code into procedures defined within the process. For example:
process (empty) is
procedure assign_something (
index : natural;
something : std_logic_vector(7 downto 0)
next_state : state_type
) is
begin
bus(index*8+7 downto index*8) <= something;
state <= next_state;
end procedure;
begin
wait until rising_edge(clk);
case state is
when st0_idle => ...
when st1_work0 => assign_something(0, something, st0_idle);
when st1_work1 => assign_something(1, something_else, st0_idle);
-- ... etc ...
end case;
if reset = '1' then
state <= st0_idle;
end if;
end procedure;
Hopefully you get the idea. Depending on how regular the state machine structure is, you may also want to replace the enumerated state variables that correspond to each index with a simple count or index variable that you keep track of along with the named state.
That's all up to you, but however you do it, using procedures to factor out common code whenever you can will probably make your VHDL much easier to work with.
Applying this change would make the code look something like this:
architecture ...
type state_type is (st_idle, st_work);
signal state : state_type;
signal index : integer range 0 to NUM-1;
...
begin
...
process (empty) is
procedure assign_something (
index : natural;
something : std_logic_vector(7 downto 0)
next_state : state_type
) is
begin
bus(index*8+7 downto index*8) <= something;
state <= next_state;
end procedure;
begin
wait until rising_edge(clk);
case state is
when st_idle =>
for i in 0 to NUM-1 loop
if empty(i) = '1' then
index := i;
exit;
end if;
end loop;
when st_work => assign_something(index, something, st_idle);
end case;
if reset = '1' then
state <= st_idle;
end if;
end procedure;
Obviously this has to be changed to match exactly what you want to do ... =)

Resources