2
\$\begingroup\$

I'm quite new to Verilog. I have some code working, but from time to time, I get some incomprehensible behavior, and I think I lack some knowledge in Verilog.

Here is a quick example of a more complex project. It works with the div2 module (/* go */), and it doesn't with the div5 module (/* no go */). Go / no go means I got ssoc signal on LED2 debug output or not.

module test_div_1(
 /* iCEstick clk (12MHz) */
 input clkin,
 /* 10MHz ref_in */
 input ref_in,
 /* iCEstick leds */
 output LED_GREEN, 
 output LED0, output LED1, output LED2, output LED3,
 /* ADC (DIV) spi */
 ); 
 
 SB_PLL40_CORE #(
 .FEEDBACK_PATH("SIMPLE"),
 /* $ icepll -i 12 -o 30 */
 /* clkin=12MHz */
 .DIVR(0), /* DIVR = 0 (div 1) */
 .DIVF(79), /* DIVF = 79 (x80) */
 .DIVQ(5), /* DIVQ = 5 (div 6) */
 /* main_clk=30MHz */
 .FILTER_RANGE(3'b001) /* FILTER_RANGE = 1 */
 ) uut (
 .LOCK(LED_GREEN),
 .RESETB(1'b1),
 .BYPASS(1'b0),
 .REFERENCECLK(clkin),
 .PLLOUTCORE(main_clk)
 );
 
 
 wire main_clk;
 wire ref_in;
 wire soc; 
 reg ssoc;
 wire spi_m_clk;
 
 /* soc generator (125kHz) */
 div80 d80_1(ref_in, soc);
 
 /* cs and clk generation */
/* -----\/----- EXCLUDED -----\/-----
 div2 div_spi_clk(ref_in, spi_m_clk); /-* go *-/
 -----/\----- EXCLUDED -----/\----- */
 div5 div_spi_clk(ref_in, spi_m_clk); /* no go */
 always @ (negedge spi_m_clk)
 ssoc<=soc;
 
 
 /* TODO: remove (debug) */
 assign LED0=spi_m_clk;
 assign LED1=soc;
 assign LED2=ssoc;
 assign LED3=1'b0; 
endmodule /* # test_div_1 end # */
module div80(input in,
 output out);
 wire in;
 reg out;
 reg [6:0] c;
 initial
 begin
 c=7'b0000000;
 end
 
 always@(posedge in)
 begin
 if(c>=79)
 begin
 c<=0;
 out<=1'b1;
 end
 else
 begin
 out<=1'b0;
 c<=c+1;
 end
 end
 
endmodule /* # div80 end # */
module div5(input in,
 output out);
 wire in;
 reg out;
 reg [2:0] c;
 
 initial
 begin
 c=3'b000;
 end
 
 always@(posedge in)
 begin
 if(c>=4)
 begin
 c<=0;
 out<=1'b1;
 end
 else
 begin
 out<=1'b0;
 c<=c+1;
 end
 end
endmodule /* # div5 end # */
module div2(input in,
 output out);
 wire in, out;
 reg c;
 always@(posedge in)
 begin
 c<=!c;
 end
 assign out=c;
endmodule /* # div2 end # */

The div80 module output works fine.

Is my mistake related to something about wire/reg, or anything else?

I'm using ice40stick and icestorm toolchain (yosys, nextpnr and icepack).

Could you help me understand why my design does not behave properly?

toolic
10.8k11 gold badges31 silver badges35 bronze badges
asked Oct 6, 2023 at 16:52
\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

When I try to compile your code with a couple simulators, I get multiple warning for your div5 and div2 modules. If you do not get warning messages with your simulator, try your code on the simulators on EDAPlayground.

Here is the code without any warnings:

module div5(input in,
 output reg out);
 reg [2:0] c;
 initial
 begin
 c=3'b000;
 end
 always@(posedge in)
 begin
 if(c>=4)
 begin
 c<=0;
 out<=1'b1;
 end
 else
 begin
 out<=1'b0;
 c<=c+1;
 end
 end
endmodule /* # div5 end # */
module div2(input in,
 output out);
 reg c;
 always@(posedge in)
 begin
 c<=!c;
 end
 assign out=c;
endmodule /* # div2 end # */

In div5, you make assignments to out from procedural code (always block). This means you need to declare out as reg. In div2, you use a procedural assign statement, which means you should not declare it as a reg.

answered Oct 6, 2023 at 17:21
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.