- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Hi,
I´m newbie on Verilog, actually also in System Verilog, but worked long time ago with VHDL and C++ languages. I used a template of a Moore state machine from ALTERA for Verilog, and performed some changes in order to start the learning. However, during simulation, I can´t see any change at both the variables currentstate.level_main and currentstate.level_sub. I took the care to perform reset during simulation.module moore_mac
(
input clk, data_in, reset,
output reg data_out
);
reg sub_state3, state ;
parameter S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011 ;
parameter S3_0 = 3'b100, S3_1 = 3'b101, S3_2 = 3'b110 ;
typedef enum { SM0 , SM1 , SM2 , SM3 } STATE_MACHINE ;
typedef enum { SM0_S, SM1_S, SM2_S, SM3_S } STATE_MACHINE_S ;
typedef struct {
reg Level_main ;
reg Level_sub ;
} FSM ;
FSM CurrentState ;
// Determine the next state
always @ ( posedge clk or posedge reset )
begin
if (reset)
begin
state <= S1 ;
sub_state3 <= S3_0 ;
CurrentState.Level_main <= S0 ;
CurrentState.Level_sub <= S3_0 ;
end
else
case (state)
S0:
state <= S1;
S1:
if (data_in) state <= S1;
else state <= S2;
S2:
if (data_in) state <= S1;
else state <= S3;
S3:
state <= next_state ( sub_state3 ) ;
endcase
end
// Output depends only on the current state
always @ (state)
begin
case (state)
S0:
data_out = S0 ;
S1:
data_out = S1 ;
S2:
data_out = S2 ;
S3:
data_out = S3 ;
default:
data_out = S0 ;
endcase
end
// *******************************************************
// Gets next state, by assessing corresponding sub_state
// *******************************************************
function next_state ;
input reg valSubstateBefore ;
reg valSubstateAfter ;
if ( valSubstateBefore < S3_2 )
begin
valSubstateAfter = valSubstateBefore + 1 ;
state = state ;
end
else
begin
valSubstateAfter = S3_0 ;
state = S0 ;
end
sub_state3 = valSubstateAfter ;
next_state = state ;
endfunction
// *******************************************************
endmodule
Thanks in advance. Andre
링크가 복사됨
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Thats because you only assign them values in the reset state.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Thanks Trcky, but after reset state, the registers wouldn´t not keep these values ?
I mean, if I understood correctly, the code bellow stores some values that will remain after reset, or I´m wrong ?if (reset)
begin
CurrentState.Level_main <= S0 ;
CurrentState.Level_sub <= S3_0 ;
end
If not, is there any way to do this in the synthesis?
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
There are no registers described here. CurrentState is a variable that is being set at reset, and then never changing again. So the synthesisor will just assign them as constants.
Level_main and level_sub both initialise to 3'b0. At reset level_sub should be getting set to 3'b100 What exactly is going wrong? in a synthesised system this variable would just dissapear as it has no effect on any output.- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
--- Quote Start --- level_main and level_sub both initialise to 3'b0. At reset level_sub should be getting set to 3'b100 What exactly is going wrong? --- Quote End --- That´s the problem: Running simulation, both these 2 variables show "0" on their contents. Once this is the first time I use the QuartusII IDE, I'm not sure if I´m doing something wrong in the code or just an inadequate use of the sotware. [EDIT] I´m starting reset with 1 for few nano seconds, releasing to 0 afterward.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
what are you simulating, RTL or gate netlist?
are you using modelsim? where is the testbench?- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Hi Tricky,
I´m using default simulator from QuartusII; in other words, I didn´t configured anyone, leaving as <NONE>, according to page 7 of this (ftp://ftp.altera.com/up/pub/tutorials/de2/digital_logic/tut_quartus_intro_verilog.pdf) tutorial, and the input signals are being generated directly on Waveform Editor. The file that contains the project files are attached, and output picture bellow. Please note that the whole design are working, except the above mentioned variables ( optimized as constants, as you said ) which are read on simulation as "0" value, wherever I place the cursor. http://www.alteraforum.com/forum/attachment.php?attachmentid=10190&stc=1- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Theres your problem. The quartus simulator simulates the netlist. And as your CurrentState variable does nothing, it is removed during synthesis.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Ok I got, but I´m not sure if this feature is useful during developing.
There is some way for me to "force" such a synthesis ? Sometimes is quite useful perform simple constructs and simple simulations whose structure will be further improved.- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
If you did an rtl simulation, with an rtl simulator (like modelsim that you can get for free with quartus) then you would see all of your variable work as you intended.
The quartus simulator is very limited.- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Fine, I´m currently downloading the Modelsim pack, but I confess that I didn't understand something: You said before on post# 7 that these unused states were removed during synthesis, but if Modelsim acts on scope of simulation which occurs sequentially after, how would both variables would be viewable if were supposedly removed ?
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Modelsim simulates your code as you wrote it. So you can see all variables in the code. Its not synthesised at all, just compiled.
Quartus simulates the synthesised version.- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Ohh, sorry for mistake. I´ll install the Modelsim and will update here with results.
Thanks for kind support.- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
I had some problems to activate Modelsim license due to issues regarded to system environment variables. Anyway, I decided to work with the simulation performed on synthesised version of the code, due I´m assuming that this could yield a more realistic result, once runs directly into the technology on what will be assembled.
Back to the code, I wish ask a new question, now related to struct usage on functions, more specifically: how to use a 'struct' variable into a function, either as input and output ? I´m using the code bellow, which has few enhancements on the other posted before. The function next_state instantiated at line 71, and declared at the line 97 which according to lines 115-116 has output of the type fsm_t, do not update correctly its values. I´m convinced that I did not performed the correct association of inputs at the lines 98-99. due do match to the same fsm_t type used at the output. Could so please inform what I´m doing wrong, or just suggest a link were I could learn how could I create and instantiate a function using a struct variable at input and output ? Many thanks in advance.//`define DEBUG_MODE
module moore_mac
(
input clk, data_in, reset,
output reg data_out
);
//******************************* Parameter definitions
typedef enum logic { SM0, SM1, SM2, SM3, SM3_0, SM3_1, SM3_2, SM3_3 } fmstate ;
fmstate nstate, pstate ;
parameter S0 = 3'b000 ;
parameter S1 = 3'b001 ;
parameter S2 = 3'b010 ;
parameter S3 = 3'b011 ;
parameter S3_0 = 3'b100 ;
parameter S3_1 = 3'b101 ;
parameter S3_2 = 3'b110 ;
parameter S3_3 = 3'b111 ;
//******************************* Type declarations
typedef struct packed {
reg Level_main ;
reg Level_sub ;
} FSM ;
typedef struct packed {
bit Level_main_t ;
bit Level_sub_t ;
} FSM_t ;
//******************************* Varable declarations
FSM_t tempCurrentState ; // State machine index ( temporary )
FSM CurrentState ; // State machine index ( current )
//`ifdef DEBUG_MODE
reg Debug_counter ;
//`endif
//********************************** Determine the next state
always @ ( posedge clk or posedge reset )
begin
if (reset)
begin
//`ifdef DEBUG_MODE
Debug_counter <= 0 ;
//`endif ;
CurrentState.Level_main <= S0 ;
CurrentState.Level_sub <= S3_0 ;
end
else
begin
//`ifdef DEBUG_MODE
Debug_counter <= Debug_counter + 1 ;
//`endif
case (CurrentState.Level_main)
S0:
CurrentState.Level_main <= S1;
S1:
if (data_in) CurrentState.Level_main <= S1;
else CurrentState.Level_main <= S2;
S2:
if (data_in) CurrentState.Level_main <= S1;
else CurrentState.Level_main <= S3;
S3:
CurrentState <= next_state ( CurrentState.Level_main , CurrentState.Level_sub ) ;
endcase
end
end
//********************************** Determine the output value
always @ ( CurrentState.Level_main )
begin
case ( CurrentState.Level_main )
S0:
data_out = S0 ;
S1:
data_out = S1 ;
S2:
data_out = S2 ;
S3:
data_out = S3 ;
default:
data_out = S0 ;
endcase
end
// *******************************************************
// Gets next state, by assessing corresponding sub_state
// *******************************************************
function FSM_t next_state ;
input reg valStateBefore ;
input reg valSubstateBefore ;
reg valStateAfter ;
reg valSubstateAfter ;
if ( valSubstateBefore < S3_3 )
begin
valStateAfter = valStateBefore ;
valSubstateAfter = valSubstateBefore + 1 ;
end
else
begin
valStateAfter = S0 ;
valSubstateAfter = S3_0 ;
end
next_state.Level_main_t = valStateAfter ;
next_state.Level_sub_t = valSubstateAfter ;
endfunction
endmodule
note: Please consider the fact that this code is only a temporary draft, so that some small problems flagged by the compiler as "Warnings" will be fixed later.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
I highly recommend you get modelsim working, as it allows you to put debug anywhere in your code, with system calls like $display, that you cannot do with synthesised code.
Btw, you didnt instantiate a function - you called the function. Instantiation is only done on modules. Also, the reg type is pretty redundant in SV now. It's also a bit of a misnomer, as a reg variable doesnt neccessarily make a register. Much better to use the logic type. If you want to be sure you put stuff in the right order, use named association (and btw, your function definition is old style). I think it read better with:
function FSM_t next_state( reg valStateBefore, reg valSubStateBefore);
FSM_t my_return_variable;
....
return my_return_variable;
endfunction;
// and then have explicit named association
a_variable <= next_state( .valStateBefore( something), .valSubStateBefore( something_else) )
and use an explicit return, but thats just mean coming from a VHDL background. Does this function really have any merit? this is really just another bit of code that could sit in the always block. Not eactly doing a lot. What exactly isnt working?
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Hi Tricky,
Thanks for the quick reply; I changed the function declaration with the improvements that you suggested, and in fact now its constructs appears much more consistent with a good coding practice than the one I posted earlier; I´m coding based on several examples spread on the Web what explains the old style. However after compiling the changes on the function... --- Quote Start ---function FSM_t next_state( reg valStateBefore, reg valSubStateBefore );
FSM_t next_state_return ;
...
return next_state_return ;
endfunction
- Error (10170): Verilog HDL syntax error at moore_mac.sv(98) near text "reg"; expecting ")"
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
--- Quote Start --- Hi Tricky, Thanks for the quick reply; I changed the function declaration with the improvements that you suggested, and in fact now its constructs appears much more consistent with a good coding practice than the one I posted earlier; I´m coding based on several examples spread on the Web what explains the old style. However after compiling the changes on the function... ...occurred the error highlighted on header above, which I could not determine how to fix it, although some most recent researches on the web. --- Quote End --- try putting the [] after the function parameter. (logic valStateBefore[2:0],...) --- Quote Start --- With respect to Modelsim, I have not given up, I really need a more powerful tool, and have to solve the problem of installation, but I'm trying to compile the code in the meantime. --- Quote End --- You will struggle to find one, modelsim is one of the most powerful simulators out there. You might use NCSim if you're doing asics, but modelsim has all sorts of features quartus and vivado (xilinx equivolent tool) will never have: RTL Simulation Gate level simulation Code coverage Mixed langauge simulation Design Profilers SV Assertions UVM Support ETc etc. --- Quote Start --- Ok, I had wrongly employed the term instantiation when I was actually referring to function call. Anyway, it was not what I done at the line 71 of the code posted above ? currentstate <= next_state ( ... ) ; --- Quote End --- No, this is just calling next_state function. You code has no instantitation. --- Quote Start --- As I mentioned before, this is just a preliminary draft of a code whose purpose is to work as a template to a state machine which will work with 2 levels of states. Once the current state falls into certain states, there must run other another levels of state machines ( which I named as substates ). The application which is currently working, was wrote in C language and has dozens of states. In order to achieve a clean and structured code, I was wondering if I could create a skeleton for the code which would work as a template to insert the remaining system behaviors. Someone could suggest to me adopt a better approach such as using IP cores, but the purpose of such a development is mainly learning of the SV language features. Once again, thanks for the assistance. --- Quote End --- This kind of explains alot. Direct ports of C to HDL never really work very well. It would be much better to try and re-enginner the system for a hardware platform. What are the end-goals? What is the source data? Have you got a circuit diagram of your intended architecture? This should be the first step before writing any HDL (its a description language after all, without the circuit, how do you expect to describe it?) As to this example, I would suggest forgetting about functions. Functions and tasks in HDL should only really be used to tidy away code that is repeated over and over. Given your description, I would forget about having a struct with two states, just have two discrete variables. Have one working in one always block, and the second in another always block that is only active when the first is in the correct state:
always @(posedge clk)
begin
// Main state machine
end
always @(posedge clk)
begin
if (main_state == correct_state) begin
//sub sstate machine
end
end
But Persoanlly, I think a re-design is in order, as it is very rare that you need two state machines. Maybe you need two modules that handle two separate things?
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Hi Tricky,
. --- Quote Start --- try putting the [] after the function parameter --- Quote End --- I done that, but didn´t work yet; returns the same error as posted above (http://www.alteraforum.com/forum/showthread.php?t=47733&p=196390#post196390) on post# 16, even made all the changes proposed. It should not to be so hard to make a simple function in SV having the same struct type, either in Input and Output --- Quote Start --- Have you got a circuit diagram of your intended architecture? This should be the first step before writing any HDL (its a description language after all, without the circuit, how do you expect to describe it?) --- Quote End --- The operating principle is so simple, that is not even worthy of elaboration of a state diagram. Basically it is a state sequencer, a kind of up counter (represented by the main state in each case statement), which eventually in some states, must remain there, then running machines of internal states. --- Quote Start --- Given your description, I would forget about having a struct with two states, just have two discrete variables. Have one working in one always block, and the second in another always block that is only active when the first is in the correct state --- Quote End --- Note at this link here (http://www.mcu.net.br/phpbb/blog.php?action=view&article_id=13) ( not translated ) that there is state amount somewhat in the order of almost 100, what substantiate to me try to do something more elaborate, removing the working of substates processing from the allways block, and then putting it into specific functions (which as I said, is still in a draft form). The logic behind the encapsulation of the variables into a single type, it is because I intend to define States and Substates numerically so that with a simple math, it is possible to know when it was reached the end of Substates, and then be able to continue on to the next upper level state. This logic will not present here a while just for we focus the attention in the main question. I will certainly consider the suggestions that you put up on redesign, but the reason for what I insist on trying to solve the initial question (function with struct with in and out) is to allow me to learn the available resources SV language. --- Quote Start --- I would suggest forgetting about functions. Functions and tasks in HDL should only really be used to tidy away code that is repeated over and over --- Quote End --- This function will be used in several parts of the program. As I mentioned, the entire code above is just a template. Anway, now it has become a matter of honor, a personal challenge : Regardless if in the course of this project I will adopt another approach like the one you suggested, I really wish to know how to implement a struct based function, used at either input and output. Many thanks for your support. Andre.- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Problem fixed, just to share ( not optimized ):
--- Quote Start --- type declaration typedef struct packed {
reg Level_main ;
reg Level_sub ;
} FSM ;
typedef struct packed {
bit Level_main_t ;
bit Level_sub_t ;
} FSM_t ;
variable declaration FSM_t tempCurrentState ; // State machine index ( temporary )
FSM CurrentState ; // State machine index ( current )
function declaration function FSM_t next_state( input logic valStateBefore , input logic valSubstateBefore );
FSM_t next_state_return ;
...
return next_state_return ;
endfunction
function call CurrentState <= next_state ( CurrentState.Level_main , CurrentState.Level_sub ) ;
--- Quote End --- Thanks for your help. Andre
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
I´m currently using the structure bellow at a function that handles both its inputs and outputs as type fsm_t.
typedef struct packed {
bit Level_main_t ;
bit Level_sub_t ;
bit Level_subcurr_t ;
} FSM_t ;
That is something like that: function FSM_t next_state ( input ...)
FSM_t next_state_return ;
...
return next_state_return ;
endfunction
Once I need to use at the block a reg variable having the same format to exchange values, I performed the following : typedef struct packed {
reg Level_main ;
reg Level_sub ;
reg Level_subcurr ;
} FSM ;
...and created the variable bellow: FSM StateMachine ;
However, I don´t like the above code arrangement, due I employed a structure duplicated with the same format. Does it have any way to perform such a declaration on a smarter way, as for example with only the type fsm_t ?
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
why not just declare FSM_t as logic? (which is basically the same as reg).
