[SOLVED] Why is my Verilog not generating a triangle wave with a counter?

Status
Not open for further replies.

hobbskw

Junior Member level 3
Joined
Oct 19, 2021
Messages
25
Helped
1
Reputation
2
Reaction score
1
Trophy points
3
Activity points
197
Hello,
I have written code to generate a simple triangle wave that varies from -1250 to 1250 (-MAX to +MAX). I used MATLAB to verify that the logic itself works for generating a triangle wave, by copy/pasting the code into MATLAB and making minor syntax changes so it would work in that environment. However, when I simulate it in Vivado, the counter variable only alternates between 1 and 0 and does not count up to MAX or down to -MAX. I suspect there is something wrong with how the code is written in Verilog. Would anyone be able to shed light on this problem? I would greatly appreciate any help!

Code:
Code:
`timescale 1ns / 1ps

module sine_LUT(
        input clk,
        output led
    );

reg[12:0] counter = 0;
integer updown = 1;
localparam  MAX = 1250;

always@(posedge clk) begin
    if (counter > MAX)
        begin
            counter <= MAX;
            updown <= updown * -1;
        end
    if (counter < MAX*(-1))
        begin
            counter <= MAX*(-1);
            updown <= updown * -1;
        end
    counter <= counter + updown;
end

assign led = (counter < 20)?1:0;
endmodule

Testbench code:
Code:
`timescale 1ns / 1ps

module testbenchh;
reg clk = 0;
wire led;
sine_LUT UUT (clk, led);
always #5 clk = ~clk;

endmodule

Simulation result:


MATLAB code:
Code:
clc
clear
counter = 0;
updown = 1;
MAX = 1250;
T = 10000;

val = zeros(T);
time = zeros(T);

for t = 1:T
    if (counter > MAX)
            counter = MAX;
            updown = updown * -1;
    end
    if (counter < MAX*(-1))
            counter = MAX*(-1);
            updown = updown * -1;
    end
    counter = counter + updown;
    val(t) = counter;
    time(t) = t;
end

plot(time, val);
xlim([0 T]);

MATLAB result:
 

First of all, why bother using MATLAB to simulate Verilog, when there are tools specifically designed for that task? Once you "make minor syntax changes", all bets are off.

I think you should also look at the updown variable in the simulation. You'll probably see it changing state every other clock.

Verilog is not my native language, but I believe your problem is that you're comparing a reg to an integer. reg doesn't know anything about "sign", so it thinks 0 (counter) is less than xFFFF.
 
Last edited:

Hello Barry,
Thank you, yes it was not liking me comparing reg to integer. It was also having some problems when counter reached below 0. I changed everything to integer, and also shifted everything to stick to positive values, and it finally works. Thank you for your help!
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…