Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Led_blinker example #17

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions examples/Led_blinker/Led_blinker.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
module Led_blinker
(
i_clock,
i_reset,
i_enable,
i_switch_1,
i_switch_2,
o_led_drive
);

input i_clock;
input i_reset;
input i_enable;
input i_switch_1;
input i_switch_2;
output o_led_drive;

parameter c_CNT_100HZ = 125;
parameter c_CNT_50HZ = 250;
parameter c_CNT_10HZ = 1250;
parameter c_CNT_1HZ = 12500;

reg [31:0] r_CNT_100HZ = 0;
reg [31:0] r_CNT_50HZ = 0;
reg [31:0] r_CNT_10HZ = 0;
reg [31:0] r_CNT_1HZ = 0;

reg r_TOGGLE_100HZ = 1'b0;
reg r_TOGGLE_50HZ = 1'b0;
reg r_TOGGLE_10HZ = 1'b0;
reg r_TOGGLE_1HZ = 1'b0;

reg r_LED_SELECT = 1'b0;

always @(posedge i_clock)
begin
if (i_reset == 1)
begin
r_CNT_100HZ <= 0;
r_CNT_50HZ <= 0;
r_CNT_10HZ <= 0;
r_CNT_1HZ <= 0;

r_TOGGLE_100HZ <= 0;
r_TOGGLE_50HZ <= 0;
r_TOGGLE_10HZ <= 0;
r_TOGGLE_1HZ <= 0;
end
end

always @(posedge i_clock)
begin
if (r_CNT_100HZ == c_CNT_100HZ - 1)
begin
r_TOGGLE_100HZ <= !r_TOGGLE_100HZ;
r_CNT_100HZ <= 0;
end
else
r_CNT_100HZ <= r_CNT_100HZ + 1;
end

always @(posedge i_clock)
begin
if (r_CNT_50HZ == c_CNT_50HZ - 1)
begin
r_TOGGLE_50HZ <= !r_TOGGLE_50HZ;
r_CNT_50HZ <= 0;
end
else
r_CNT_50HZ <= r_CNT_50HZ + 1;
end

always @(posedge i_clock)
begin
if (r_CNT_10HZ == c_CNT_10HZ - 1)
begin
r_TOGGLE_10HZ <= !r_TOGGLE_10HZ;
r_CNT_10HZ <= 0;
end
else
r_CNT_10HZ <= r_CNT_10HZ + 1;
end

always @(posedge i_clock)
begin
if (r_CNT_1HZ == c_CNT_1HZ - 1)
begin
r_TOGGLE_1HZ <= !r_TOGGLE_1HZ;
r_CNT_1HZ <= 0;
end
else
r_CNT_1HZ <= r_CNT_1HZ + 1;
end

always @(*) begin
case ({i_switch_1, i_switch_2})
/* verilator lint_off COMBDLY */
2'b11 : r_LED_SELECT <= r_TOGGLE_1HZ;
2'b10 : r_LED_SELECT <= r_TOGGLE_10HZ;
2'b01 : r_LED_SELECT <= r_TOGGLE_50HZ;
2'b00 : r_LED_SELECT <= r_TOGGLE_100HZ;
/* verilator lint_on COMBDLY */
endcase
end

assign o_led_drive = r_LED_SELECT & i_enable;

endmodule
32 changes: 32 additions & 0 deletions examples/Led_blinker/config.gtkw
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[*]
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
[*] Fri Mar 8 17:16:35 2024
[*]
[dumpfile] "/home/magnus/ntnu/orbit/biosat-electronics-FPGA/electronics-verilator/examples/Led_blinker/trace.vcd"
[dumpfile_mtime] "Fri Mar 8 17:13:28 2024"
[dumpfile_size] 49174
[savefile] "/home/magnus/ntnu/orbit/biosat-electronics-FPGA/electronics-verilator/examples/Led_blinker/config.gtkw"
[timestart] 0
[size] 1850 1016
[pos] -51 -51
*0.000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] TOP.
[sst_width] 233
[signals_width] 166
[sst_expanded] 1
[sst_vpaned_height] 289
@28
TOP.Led_blinker.i_clock
TOP.Led_blinker.i_enable
TOP.Led_blinker.i_reset
TOP.Led_blinker.i_switch_1
TOP.Led_blinker.i_switch_2
TOP.Led_blinker.o_led_drive
@22
TOP.Led_blinker.r_CNT_1HZ[31:0]
TOP.Led_blinker.r_CNT_10HZ[31:0]
TOP.Led_blinker.r_CNT_50HZ[31:0]
@23
TOP.Led_blinker.r_CNT_100HZ[31:0]
[pattern_trace] 1
[pattern_trace] 0
6 changes: 6 additions & 0 deletions examples/Led_blinker/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
VERILATOR_ROOT := ../..
PROJECT_NAME := Led_blinker
SOURCES := *.sv
SIMFILES := *.cpp

include $(VERILATOR_ROOT)/verilator.mk
100 changes: 100 additions & 0 deletions examples/Led_blinker/sim.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include "VLed_blinker.h"
#include "verilated.h"

// Needed for waveform generation
#include <verilated_vcd_c.h>

#include <cassert>
#include <vector>
#include <iostream>

void toggle_clk(VLed_blinker* top, VerilatedVcdC *trace, uint32_t *tickcount) {
top->i_clock = 0;
top->eval();
trace->dump(10 * (*tickcount)++);
top->i_clock = 1;
top->eval();
trace->dump(10 * (*tickcount)++);
}

void print_top(VLed_blinker *top) {
printf("i_enable: %i\n", top->i_enable);
printf("i_clock: %i\n", top->i_clock);
printf("i_switch_1: %i\n", top->i_switch_1);
printf("i_switch_2: %i\n", top->i_switch_2);
printf("o_led_drive: %i\n", top->o_led_drive);
}

int main(int argc, char** argv) {
VLed_blinker* top = new VLed_blinker;
Verilated::commandArgs(argc, argv);

// For waveform generation
uint32_t tickcount = 0;
Verilated::traceEverOn(true);

// Initialization of trace
VerilatedVcdC *trace = new VerilatedVcdC;
top->trace(trace, 99);
trace->open("trace.vcd");

// Set initial values
top->i_enable = 1;
top->i_reset = 0;
top->i_clock = 0;
top->i_switch_1 = 0;
top->i_switch_2 = 0;
top->eval();

int ret = 0;
uint32_t count_limits[] = {
125,
250,
1250,
12500
};
uint32_t count = 0;

for (int i = 0; i < sizeof(count_limits) / sizeof(count_limits[0]); i++) {
if (Verilated::gotFinish()) break;

top->i_switch_1 = (i & 0b01) ? 1 : 0;
top->i_switch_2 = (i & 0b10) ? 1 : 0;
top->i_reset = 0;

uint32_t count_limit = count_limits[i];
bool led_signal_expect = false;
for (int j = 0; j < 2*count_limit; j++) {
if (count == count_limit) {
led_signal_expect = true;
printf("Expect led signal high\n");
} else if (count == 2*count_limit) {
led_signal_expect = false;
printf("Expect led signal low\n");
}

if (top->o_led_drive != led_signal_expect) {
printf("top->o_led_drive: Got %i when %i expected\n", top->o_led_drive, led_signal_expect);
toggle_clk(top, trace, &tickcount);
ret = 1;
goto out;
}

toggle_clk(top, trace, &tickcount);
printf("\nit: %i\n", j);
print_top(top);
fflush(stdout);
count++;
}

printf("Toggled clock %i times. Reset\n", 2*count);
fflush(stdout);
}

out:
trace->close();
delete trace;

delete top;
return ret;
}
Loading