I developed this code for a Graph convolutional network (GCN) module in system verilog:
module GCN
#(parameter FEATURE_COLS = 96,
parameter WEIGHT_ROWS = 96,
parameter FEATURE_ROWS = 6,
parameter WEIGHT_COLS = 3,
parameter FEATURE_WIDTH = 5,
parameter WEIGHT_WIDTH = 5,
parameter DOT_PROD_WIDTH = 16,
parameter ADDRESS_WIDTH = 13,
parameter COUNTER_WEIGHT_WIDTH = $clog2(WEIGHT_COLS),
parameter COUNTER_FEATURE_WIDTH = $clog2(FEATURE_ROWS),
parameter MAX_ADDRESS_WIDTH = 2,
parameter NUM_OF_NODES = 6,
parameter COO_NUM_OF_COLS = 6,
parameter COO_NUM_OF_ROWS = 2,
parameter COO_BW = $clog2(COO_NUM_OF_COLS)
)
(
input logic clk, // Clock
input logic reset, // Reset
input logic start,
input logic [WEIGHT_WIDTH-1:0] data_in [0:WEIGHT_ROWS-1], //FM and WM Data
input logic [COO_BW - 1:0] coo_in [0:1], //row 0 and row 1 of the COO Stream
output logic [COO_BW - 1:0] coo_address, // The column of the COO Matrix
output logic [ADDRESS_WIDTH-1:0] read_address, // The Address to read the FM and WM Data
output logic enable_read, // Enabling the Read of the FM and WM Data
output logic done, // Done signal indicating that all the calculations have been completed
output logic [MAX_ADDRESS_WIDTH - 1:0] max_addi_answer [0:FEATURE_ROWS - 1] // The answer to the argmax and matrix multiplication
);
// Internal signals
logic [FEATURE_WIDTH-1:0] feature_matrix [0:FEATURE_ROWS-1][0:FEATURE_COLS-1];
logic [WEIGHT_WIDTH-1:0] weight_matrix [0:WEIGHT_ROWS-1][0:WEIGHT_COLS-1];
logic [DOT_PROD_WIDTH-1:0] transformed_features [0:FEATURE_ROWS-1][0:WEIGHT_COLS-1];
logic [DOT_PROD_WIDTH-1:0] aggregated_features [0:FEATURE_ROWS-1];
logic [COUNTER_FEATURE_WIDTH-1:0] node_counter;
logic [COUNTER_WEIGHT_WIDTH-1:0] weight_counter;
logic processing;
// Pipelining flip-flops for inputs and outputs
always_ff @(posedge clk or posedge reset) begin
if (reset) begin
enable_read <= 1'b0;
done <= 1'b0;
end else if (start) begin
enable_read <= 1'b1;
processing <= 1'b1;
end else if (processing) begin
enable_read <= 1'b0;
end
end
// Reading COO matrix
always_ff @(posedge clk or posedge reset) begin
if (reset) begin
coo_address <= 0;
end else if (enable_read) begin
coo_address <= coo_address + 1;
end
end
// Feature transformation
always_comb begin
for (int i = 0; i < FEATURE_ROWS; i++) begin
for (int j = 0; j < WEIGHT_COLS; j++) begin
transformed_features[i][j] = '0;
for (int k = 0; k < FEATURE_COLS; k++) begin
transformed_features[i][j] += feature_matrix[i][k] * weight_matrix[k][j];
end
end
end
end
// Aggregation (vector addition)
always_comb begin
for (int i = 0; i < FEATURE_ROWS; i++) begin
aggregated_features[i] = '0;
for (int j = 0; j < COO_NUM_OF_COLS; j++) begin
aggregated_features[i] += transformed_features[coo_in[0][j]][coo_in[1][j]];
end
end
end
// Argmax function
always_comb begin
for (int i = 0; i < FEATURE_ROWS; i++) begin
max_addi_answer[i] = '0;
for (int j = 1; j < WEIGHT_COLS; j++) begin
if (aggregated_features[i] < transformed_features[i][j]) begin
max_addi_answer[i] = j;
end
end
end
end
// Done signal
always_ff @(posedge clk or posedge reset) begin
if (reset) begin
done <= 1'b0;
end else if (processing) begin
done <= 1'b1;
end
end
endmodule
I ran this code for synthesis via dc_shell and got the following error:
Warning: path/Lab4/GCN/systemVerilog//verilog.sv:94: signed to unsigned assignment occurs. (VER-318)
Warning: path/GCN/systemVerilog//verilog.sv:101: Net done or a directly connected net may be driven by more than one process or block. (ELAB-405)
Inferred memory devices in process
in routine GCN line 45 in file
'path/GCN/systemVerilog//verilog.sv'.
===============================================================================
| Register Name | Type | Width | Bus | MB | AR | AS | SR | SS | ST |
===============================================================================
| processing_reg | Flip-flop | 1 | N | N | N | N | N | N | N |
| enable_read_reg | Flip-flop | 1 | N | N | Y | N | N | N | N |
| done_reg | Latch | 1 | N | N | Y | N | - | - | - |
===============================================================================
Inferred memory devices in process
in routine GCN line 58 in file
'path/GCN/systemVerilog//verilog.sv'.
===============================================================================
| Register Name | Type | Width | Bus | MB | AR | AS | SR | SS | ST |
===============================================================================
| coo_address_reg | Flip-flop | 3 | Y | N | Y | N | N | N | N |
===============================================================================
Inferred memory devices in process
in routine GCN line 101 in file
'path/GCN/systemVerilog//verilog.sv'.
===============================================================================
| Register Name | Type | Width | Bus | MB | AR | AS | SR | SS | ST |
===============================================================================
| done_reg2 | Flip-flop | 1 | N | N | Y | N | N | N | N |
===============================================================================
Warning: path/GCN/systemVerilog//verilog.sv:45: Netlist for always_ff block contains a latch. (ELAB-978)
Error: path/GCN/systemVerilog//verilog.sv:101: Net 'done' or a directly connected net is driven by more than one source, and not all drivers are three-state. (ELAB-366)
Presto compilation terminated with 1 errors.
I am very new to system verilog/verilog and memory devices. Any help will be appriciated.
1 Answer 1
The inferred memory message is not an error.
The error message is later on in that trace, specifically:
Error: path/GCN/systemVerilog//verilog.sv:101:
Net 'done' or a directly connected net is driven by more than one source
You have a net called done
which is driven from more than one source.
Looking at your code, you have a stray assignment to the done
signal in the first always block (line 45). Presumably a copy and paste mistake. This also explains the inferred latch warning as well. Replacing the done
on this line with what I presume is meant to be processing
will fix both the error and the warning.
// Pipelining flip-flops for inputs and outputs
always_ff @(posedge clk or posedge reset) begin
if (reset) begin
enable_read <= 1'b0;
done <= 1'b0; <<<<<<<<<<<<< Here <<<<<<
Explore related questions
See similar questions with these tags.
Inferred memory devices in process
message is an error? \$\endgroup\$