Skip to content

Commit

Permalink
f4pga systemverilog tests flattened
Browse files Browse the repository at this point in the history
  • Loading branch information
amirarjmand93 committed Dec 16, 2024
1 parent 178aca6 commit ff6dd80
Show file tree
Hide file tree
Showing 14 changed files with 755 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/nightly_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
# Prevents from running on forks where no custom runners are available
if: ${{ github.repository_owner == 'verilog-to-routing' }}

timeout-minutes: 700 #420
timeout-minutes: 420

container: ubuntu:jammy

Expand Down
16 changes: 13 additions & 3 deletions libs/EXTERNAL/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
include(ExternalProject)
include(ProcessorCount)

#Manually synchronized external libraries
add_subdirectory(libpugixml)
Expand All @@ -9,8 +10,17 @@ add_subdirectory(libsdcparse)
add_subdirectory(libblifparse)
add_subdirectory(libtatum)
add_subdirectory(libcatch2)
#add_subdirectory(synlig)
#add_subdirectory(parmys)

#Proc numbers
ProcessorCount(PROCESSOR_COUNT)

if(PROCESSOR_COUNT EQUAL 0)
# Fallback to 1 if the processor count cannot be determined
set(PROCESSOR_COUNT 1)
endif()

#VPR_USE_SERVER is initialized in the root CMakeLists
#compile sockpp only if server mode is enabled
if (VPR_USE_SERVER)
Expand Down Expand Up @@ -63,7 +73,7 @@ if (${WITH_PARMYS})
LOG_OUTPUT_ON_FAILURE ON

# dependency
DEPENDS yosys
DEPENDS yosys
)

# Synlig integration (manages Surelog and UHDM internally)
Expand Down Expand Up @@ -92,7 +102,7 @@ if (${WITH_PARMYS})
UPDATE_COMMAND git submodule update --init --recursive third_party/surelog
WORKING_DIRECTORY ${SYNLIG_SOURCE_DIR}

BUILD_COMMAND ${MAKE_PROGRAM} -C ${SYNLIG_SOURCE_DIR} install DESTDIR=${CMAKE_BINARY_DIR}/bin/synlig_install -j${CUSTOM_BUILD_PARALLEL_LEVEL}
BUILD_COMMAND ${MAKE_PROGRAM} -C ${SYNLIG_SOURCE_DIR} install DESTDIR=${CMAKE_BINARY_DIR}/bin/synlig_install -j${PROCESSOR_COUNT}
INSTALL_COMMAND ""
CONFIGURE_COMMAND ""

Expand All @@ -114,7 +124,7 @@ if (${WITH_PARMYS})
# Ensure dependencies like Yosys are built first
DEPENDS yosys # Ensure submodule sync runs before synlig build
)

endif ()
endif ()

Expand Down
12 changes: 11 additions & 1 deletion vtr_flow/benchmarks/system_verilog/f4pga/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,14 @@ This folder contains the `button_controller`, `pulse_width_led` and `timer` benc
The benchmarks are directly copied to avoid dealing with a significant amount of code by adding the F4PGA repository as a subtree to the VTR repository.
The primary purpose of these benchmarks is to utilize them in VTR GitHub CI tests to continuously monitor the functionality of the Yosys SystemVerilog and UHDM plugins.

For more information please see the ['ChipsAlliance/F4PGA'](https://github.com/chipsalliance/f4pga) Github repository.
For more information please see the ['ChipsAlliance/F4PGA'](https://github.com/chipsalliance/f4pga) Github repository.

## SystemVerilog File Flattening with `make_sv_flattened.py`

The current SystemVerilog tool, **Synlig**, cannot process multiple files as input (e.g., a top module and its dependencies). To address this limitation, use the script `make_sv_flattened.py` to flatten the files into a single SystemVerilog file. This will convert any design with dependencies into one flattened SystemVerilog file, ensuring compatibility with Synlig.

### Instructions:
1. Ensure the `make_sv_flattened.py` script is located in the folder where your SystemVerilog files (e.g., the top module and its dependencies) are gathered.
2. Run the `make_sv_flattened.py` script on the gathered files in that folder.
3. The script will output a single flattened SystemVerilog file, ready for use with Synlig.

Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
// Content from button_controller.sv
`timescale 1ns / 1ps `default_nettype none

module top (
input wire logic clk,
btnu,
btnc,
output logic [3:0] anode,
output logic [7:0] segment
);


logic sync;
logic syncToDebounce;
logic debounceToOneShot;
logic f1, f2;
logic f3, f4;
logic oneShotToCounter;
logic [7:0] counterToSevenSegment;
logic [7:0] counterToSevenSegment2;
logic oneShotToCounter2;
logic s0, s1;
debounce d0 (
.clk(clk),
.reset(btnu),
.noisy(syncToDebounce),
.debounced(debounceToOneShot)
);

assign oneShotToCounter = f1 && ~f2;

assign oneShotToCounter2 = f3 && ~f4;

timer #(.MOD_VALUE(256), .BIT_WIDTH(8)) T0 (
.clk(clk),
.reset(btnu),
.increment(oneShotToCounter),
.rolling_over(s0),
.count(counterToSevenSegment)
);

timer #(.MOD_VALUE(256), .BIT_WIDTH(8)) T1 (
.clk(clk),
.reset(btnu),
.increment(oneShotToCounter2),
.rolling_over(s1),
.count(counterToSevenSegment2)
);


display_control DC0 (
.clk(clk),
.reset(btnu),
.dataIn({counterToSevenSegment2, counterToSevenSegment}),
.digitDisplay(4'b1111),
.digitPoint(4'b0000),
.anode(anode),
.segment(segment)
);

always_ff @(posedge clk) begin

sync <= btnc;
syncToDebounce <= sync;

f1 <= debounceToOneShot;
f2 <= f1;

f3 <= syncToDebounce;
f4 <= f3;
end
endmodule


// Content from debounce.sv
`timescale 1ns / 1ps `default_nettype none

module debounce (
input wire logic clk,
reset,
noisy,
output logic debounced
);

logic timerDone, clrTimer;

typedef enum logic [1:0] {
s0,
s1,
s2,
s3,
ERR = 'X
} state_type_e;
state_type_e ns, cs;

logic [18:0] tA;

timer #(.MOD_VALUE(500000), .BIT_WIDTH(19)) T0 (
.clk(clk),
.reset(clrTimer),
.increment(1'b1),
.rolling_over(timerDone),
.count(tA)
);

always_comb begin
ns = ERR;
clrTimer = 0;
debounced = 0;

if (reset) ns = s0;
else
case (cs)
s0: begin
clrTimer = 1'b1;
if (noisy) ns = s1;
else ns = s0;
end
s1:
if (noisy && timerDone) ns = s2;
else if (noisy && ~timerDone) ns = s1;
else ns = s0;
s2: begin
debounced = 1'b1;
clrTimer = 1'b1;
if (noisy) ns = s2;
else ns = s3;
end
s3: begin
debounced = 1'b1;
if (~noisy && timerDone) ns = s0;
else if (~noisy && ~timerDone) ns = s3;
else ns = s2;
end
endcase
end

always_ff @(posedge clk) cs <= ns;
endmodule


// Content from display_control.sv
`default_nettype none

module display_control (
input wire logic clk,
input wire logic reset,
input wire logic [15:0] dataIn,
input wire logic [ 3:0] digitDisplay,
input wire logic [ 3:0] digitPoint,
output logic [ 3:0] anode,
output logic [ 7:0] segment
);

parameter integer COUNT_BITS = 17;

logic [COUNT_BITS-1:0] count_val;
logic [ 1:0] anode_select;
logic [ 3:0] cur_anode;
logic [ 3:0] cur_data_in;

always_ff @(posedge clk) begin
if (reset) count_val <= 0;
else count_val <= count_val + 1;
end

assign anode_select = count_val[COUNT_BITS-1:COUNT_BITS-2];

assign cur_anode =
(anode_select == 2'b00) ? 4'b1110 :
(anode_select == 2'b01) ? 4'b1101 :
(anode_select == 2'b10) ? 4'b1011 :
4'b0111;

assign anode = cur_anode | (~digitDisplay);

assign cur_data_in =
(anode_select == 2'b00) ? dataIn[3:0] :
(anode_select == 2'b01) ? dataIn[7:4] :
(anode_select == 2'b10) ? dataIn[11:8] :
dataIn[15:12] ;

assign segment[7] =
(anode_select == 2'b00) ? ~digitPoint[0] :
(anode_select == 2'b01) ? ~digitPoint[1] :
(anode_select == 2'b10) ? ~digitPoint[2] :
~digitPoint[3] ;

assign segment[6:0] =
(cur_data_in == 0) ? 7'b1000000 :
(cur_data_in == 1) ? 7'b1111001 :
(cur_data_in == 2) ? 7'b0100100 :
(cur_data_in == 3) ? 7'b0110000 :
(cur_data_in == 4) ? 7'b0011001 :
(cur_data_in == 5) ? 7'b0010010 :
(cur_data_in == 6) ? 7'b0000010 :
(cur_data_in == 7) ? 7'b1111000 :
(cur_data_in == 8) ? 7'b0000000 :
(cur_data_in == 9) ? 7'b0010000 :
(cur_data_in == 10) ? 7'b0001000 :
(cur_data_in == 11) ? 7'b0000011 :
(cur_data_in == 12) ? 7'b1000110 :
(cur_data_in == 13) ? 7'b0100001 :
(cur_data_in == 14) ? 7'b0000110 :
7'b0001110;


endmodule


// Content from timer.sv
`timescale 1ns / 1ps `default_nettype none

module timer #(
parameter MOD_VALUE = 1,
parameter BIT_WIDTH = 1
) (
input wire logic clk,
reset,
increment,
output logic rolling_over,
output logic [BIT_WIDTH-1:0] count = 0
);

always_ff @(posedge clk) begin
if (reset) count <= 0;
else if (increment) begin
if (rolling_over) count <= 0;
else count <= count + 1'b1;
end

end

always_comb begin
if (increment && (count == MOD_VALUE - 1)) rolling_over = 1'b1;
else rolling_over = 1'b0;
end

endmodule


Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import os
import re

def find_verilog_files():
"""Find all Verilog (.sv, .v) files in the current directory."""
return [f for f in os.listdir('.') if f.endswith(('.sv', '.v'))]

def identify_top_module(file_list):
"""Identify the file containing the top module definition."""
top_module_regex = re.compile(r"module\s+top\s*\(")
for file in file_list:
with open(file, 'r') as f:
for line in f:
if top_module_regex.search(line):
return file
return None

def create_flattened_file(top_file, file_list):
"""Create a flattened Verilog file with all file contents."""
current_dir = os.path.basename(os.getcwd())
output_file_name = f"flattened_{current_dir}.sv"

with open(output_file_name, 'w') as output_file:
if top_file:
# Write the top module first
with open(top_file, 'r') as top_module:
output_file.write(f"// Content from {top_file}\n")
output_file.write(top_module.read())
output_file.write("\n\n")

# Write the rest of the files
for file in file_list:
if file != top_file:
with open(file, 'r') as verilog_file:
output_file.write(f"// Content from {file}\n")
output_file.write(verilog_file.read())
output_file.write("\n\n")

print(f"Flattened file created: {output_file_name}")

def main():
"""Main function to generate the flattened Verilog file."""
print("Searching for Verilog files...")
verilog_files = find_verilog_files()

if not verilog_files:
print("No Verilog files found in the current directory.")
return

print("Identifying the top module...")
top_file = identify_top_module(verilog_files)

if top_file:
print(f"Top module found in: {top_file}")
else:
print("No top module found. Files will be combined in arbitrary order.")

print("Creating flattened file...")
create_flattened_file(top_file, verilog_files)

if __name__ == "__main__":
main()

Loading

0 comments on commit ff6dd80

Please sign in to comment.