ECE 755_sp23是加拿大渥太华大学(University of Ottawa)计算机工程系(School of Electrical Engineering and Computer Science)的一个研究生课程,涵盖了图神经网络(Graph Neural Networks)及其应用的基本概念和原理。该课程的主要目标是介绍最新的图神经网络模型,并探讨它们在处理图形数据、社交网络、推荐系统、自然语言处理等领域中的实际应用。该课程强调深入理解GNN模型的数学原理,并通过实验和项目作业来帮助学生巩固所学知识并提高实践技能。其中包括用Verilog实现gnn的部分。
以下是ECE 755_sp23的实验要求:
MS-1的目标是使用HDL (Verilog/System Verilog)实现嵌入在每个节点中的神经网络的推理(图2)。假设所有输入为5位,输出值为17位,输入和输出都是有符号数。顶级模块应该具有以下模块定义和输入/输出端口:
module layer_1(in1, in2, in3, in4,
w1, w2, w3, w4, out,
clk);
input clk;
input signed[4:0] in1, in2, in3, in4; //5 bit signed inputs.
input signed[4:0] w1, w2, w3, w4; //5 bit signed weight links.
output signed[11:0] out;
reg signed[4:0] in1_q, in2_q, in3_q, in4_q; //5 bit internal signals.
reg signed[4:0] w1_q, w2_q, w3_q, w4_q;
assign out = in1_q*w1_q + in2_q*w2_q + in3_q*w3_q + in4_q*w4_q;
always @(posedge clk) begin
in1_q <= in1;
in2_q <= in2;
in3_q <= in3;
in4_q <= in4;
w1_q <= w1;
w2_q <= w2;
w3_q <= w3;
w4_q <= w4;
end
endmodule
module layer_2(in1, in2, in3, in4,
w1, w2, w3, w4, out,
clk);
input clk;
input signed[11:0] in1, in2, in3, in4; //5 bit signed inputs.
input signed[4:0] w1, w2, w3, w4; //5 bit signed weight links.
output signed[16:0] out;
reg signed[11:0] in1_q, in2_q, in3_q, in4_q; //5 bit internal signals.
reg signed[11:0] w1_q, w2_q, w3_q, w4_q;
assign out = in1_q*w1_q + in2_q*w2_q + in3_q*w3_q + in4_q*w4_q;
always @(posedge clk) begin
in1_q <= in1;
in2_q <= in2;
in3_q <= in3;
in4_q <= in4;
w1_q <= w1;
w2_q <= w2;
w3_q <= w3;
w4_q <= w4;
end
endmodule
module ReLu(clk, y4, y5, y6, y7, z4, z5, z6, z7);
input clk;
input signed[11:0] y4, y5, y6, y7;
//Bits after ReLu Operation
output signed[11:0] z4, z5, z6, z7;
//Internal Signals
logic signed[11:0] y4_q, y5_q, y6_q, y7_q;
//ReLu Operation
assign z4 = (y4_q[11]) ? 'b0 : y4_q;
assign z5 = (y5_q[11]) ? 'b0 : y5_q;
assign z6 = (y6_q[11]) ? 'b0 : y6_q;
assign z7 = (y7_q[11]) ? 'b0 : y7_q;
always @(posedge clk) begin
y4_q <= y4;
y5_q <= y5;
y6_q <= y6;
y7_q <= y7;
end
endmodule
module top (
x0, x1, x2, x3,
w04, w05, w06, w07,
w14, w15, w16, w17,
w24, w25, w26, w27,
w34, w35, w36, w37,
w48, w58, w49, w59,
w68, w69, w78, w79,
out0, out1,
in_ready, out10_ready, out11_ready,
clk
);
input signed [4:0] x0, x1, x2, x3, //5 bit signed inputs and weight links.
w04, w05, w06, w07,
w14, w15, w16, w17,
w24, w25, w26, w27,
w34, w35, w36, w37,
w48, w58, w49, w59,
w68, w69, w78, w79;
input in_ready;
input clk;
output logic signed [16:0] out0, out1; //17 bit signed outputs.
output logic out10_ready, out11_ready; //Signals to indicate if outputs are ready.
//internal signals
logic signed[11:0] y4, y5, y6, y7;
logic signed[11:0] z4, z5, z6, z7;
logic in_ready1_q, in_ready2_q, in_ready3_q;
logic in_ready1, in_ready2;
//1st Stage Nodes (MAC).
layer_1 node_4(.clk(clk), .in1(x0), .in2(x1), .in3(x2), .in4(x3), .w1(w04), .w2(w14), .w3(w24), .w4(w34), .out(y4));
layer_1 node_5(.clk(clk), .in1(x0), .in2(x1), .in3(x2), .in4(x3), .w1(w05), .w2(w15), .w3(w25), .w4(w35), .out(y5));
layer_1 node_6(.clk(clk), .in1(x0), .in2(x1), .in3(x2), .in4(x3), .w1(w06), .w2(w16), .w3(w26), .w4(w36), .out(y6));
layer_1 node_7(.clk(clk), .in1(x0), .in2(x1), .in3(x2), .in4(x3), .w1(w07), .w2(w17), .w3(w27), .w4(w37), .out(y7));
always @(posedge clk) begin
in_ready1_q <= in_ready;
end
assign in_ready1 = in_ready1_q;
//ReLu Unit.
ReLu R1(.clk(clk), .y4(y4), .y5(y5), .y6(y6), .y7(y7), .z4(z4), .z5(z5), .z6(z6), .z7(z7));
//2nd Stage Nodes (MAC).
layer_2 out_node_0(.clk(clk), .in1(z4), .in2(z5), .in3(z6), .in4(z7), .w1(w48), .w2(w58), .w3(w68), .w4(w78), .out(out0));
layer_2 out_node_1(.clk(clk), .in1(z4), .in2(z5), .in3(z6), .in4(z7), .w1(w49), .w2(w59), .w3(w69), .w4(w79), .out(out1));
always @(posedge clk) begin
in_ready2_q <= in_ready1;
end
assign in_ready2 = in_ready2_q;
always @(posedge clk) begin
in_ready3_q <= in_ready2;
end
assign out10_ready = in_ready3_q;
assign out11_ready = in_ready3_q;
endmodule
top_tb.sv:
module tb_top();
reg [4:0] x0, x1, x2, x3;
reg [4:0] w04, w14, w24, w34;
reg [4:0] w05, w15, w25, w35;
reg [4:0] w06, w16, w26, w36;
reg [4:0] w07, w17, w27, w37;
reg [4:0] w48, w58, w68, w78;
reg [4:0] w49, w59, w69, w79;
reg clk;
wire [16:0] out0, out1;
wire out10_ready, out11_ready;
reg in_ready;
// Top module
// Instantiation of top module
// Please replace the instantiation with the top module of your gate level model
// Look for 'test failed' in the message. If there is no such message then your output matches the golden outputs.
top top(.x0(x0), .x1(x1), .x2(x2), .x3(x3),
.w04(w04), .w14(w14), .w24(w24), .w34(w34),
.w05(w05), .w15(w15), .w25(w25), .w35(w35),
.w06(w06), .w16(w16), .w26(w26), .w36(w36),
.w07(w07), .w17(w17), .w27(w27), .w37(w37),
.w48(w48), .w58(w58), .w68(w68), .w78(w78),
.w49(w49), .w59(w59), .w69(w69), .w79(w79),
.out0(out0), .out1(out1),
.in_ready(in_ready), .out10_ready(out10_ready), .out11_ready(out11_ready),
.clk(clk));
initial begin
clk = 0;
in_ready = 1;
x0 = 5'b00100;
x1 = 5'b00010;
x2 = 5'b00100;
x3 = 5'b00001;
w04 = 5'b00011;
w14 = 5'b00010;
w24 = 5'b01101;
w34 = 5'b11010;
w05 = 5'b10111;
w15 = 5'b00001;
w25 = 5'b11100;
w35 = 5'b01110;
w06 = 5'b00011;
w16 = 5'b00110;
w26 = 5'b10001;
w36 = 5'b01111;
w07 = 5'b01001;
w17 = 5'b10110;
w27 = 5'b01111;
w37 = 5'b10110;
w48 = 5'b00000;
w58 = 5'b11111;
w68 = 5'b00011;
w78 = 5'b10101;
w49 = 5'b10100;
w59 = 5'b10001;
w69 = 5'b10001;
w79 = 5'b00110;
#40
if (out0 == -17'd726)
$display("-----------out0 is correct-----------------");
else
$display("-----------out0 is incorrect-----------");
if (out1 == -17'd348)
$display("-----------out1 is correct-----------");
else
$display("-----------out1 is incorrect-----------");
if (out0 == -17'd726 && out1 == -17'd348)
$display("*********** ALL TESTS PASSED *********");
else
$display("*********** SOME TEST(S) FAILED *********");
end
always
#1 clk = !clk;
initial
#100 $finish;
endmodule
目标是在Verilog中实现GNN的推理。GNN的顶层模块应该具有以下模块定义和输入/输出端口。
除了MS1包含中的4个模块外,还包含以下模块:
module top ( x0_node0, x1_node0, x2_node0, x3_node0,
x0_node1, x1_node1, x2_node1, x3_node1,
x0_node2, x1_node2, x2_node2, x3_node2,
x0_node3, x1_node3, x2_node3, x3_node3,
w04, w14, w24, w34,
w05, w15, w25, w35,
w06, w16, w26, w36,
w07, w17, w27, w37,
w48, w58, w68, w78,
w49, w59, w69, w79,
out0_node0, out1_node0,
out0_node1, out1_node1,
out0_node2, out1_node2,
out0_node3, out1_node3,
in_ready,
out10_ready_node0, out11_ready_node0,
out10_ready_node1, out11_ready_node1,
out10_ready_node2, out11_ready_node2,
out10_ready_node3, out11_ready_node3,
clk);
input signed[4:0] x0_node0, x1_node0, x2_node0, x3_node0;
input signed[4:0] x0_node1, x1_node1, x2_node1, x3_node1;
input signed[4:0] x0_node2, x1_node2, x2_node2, x3_node2;
input signed[4:0] x0_node3, x1_node3, x2_node3, x3_node3;
input signed[4:0] w04, w14, w24, w34;
input signed[4:0] w05, w15, w25, w35;
input signed[4:0] w06, w16, w26, w36;
input signed[4:0] w07, w17, w27, w37;
input signed[4:0] w48, w58, w68, w78;
input signed[4:0] w49, w59, w69, w79;
input clk, in_ready;
output signed[20:0] out0_node0, out1_node0;
output signed[20:0] out0_node1, out1_node1;
output signed[20:0] out0_node2, out1_node2;
output signed[20:0] out0_node3, out1_node3;
output out10_ready_node0, out11_ready_node0;
output out10_ready_node1, out11_ready_node1;
output out10_ready_node2, out11_ready_node2;
output out10_ready_node3, out11_ready_node3;
//Implementation of GNN
logic signed[6:0] x0_node0_ag, x1_node0_ag, x2_node0_ag, x3_node0_ag;
logic signed[6:0] x0_node1_ag, x1_node1_ag, x2_node1_ag, x3_node1_ag;
logic signed[6:0] x0_node2_ag, x1_node2_ag, x2_node2_ag, x3_node2_ag;
logic signed[6:0] x0_node3_ag, x1_node3_ag, x2_node3_ag, x3_node3_ag;
//Post Relu Unit Connections
logic signed[12:0] z4_node0, z5_node0, z6_node0, z7_node0;
logic signed[12:0] z4_node1, z5_node1, z6_node1, z7_node1;
logic signed[12:0] z4_node2, z5_node2, z6_node2, z7_node2;
logic signed[12:0] z4_node3, z5_node3, z6_node3, z7_node3;
logic signed[14:0] a4_node0, a5_node0, a6_node0, a7_node0;
logic signed[14:0] a4_node1, a5_node1, a6_node1, a7_node1;
logic signed[14:0] a4_node2, a5_node2, a6_node2, a7_node2;
logic signed[14:0] a4_node3, a5_node3, a6_node3, a7_node3;
//DNNs Instantiation
dnn_top node0(.clk(clk), .x0(x0_node0_ag), .x1(x1_node0_ag), .x2(x2_node0_ag), .x3(x3_node0_ag), .in_ready(in_ready), .w04(w04), .w05(w05), .w06(w06), .w07(w07), .w14(w14), .w15(w15), .w16(w16), .w17(w17), .w24(w24), .w25(w25), .w26(w26), .w27(w27), .w34(w34), .w35(w35), .w36(w36), .w37(w37), .w48(w48), .w58(w58), .w68(w68), .w78(w78), .w49(w49), .w59(w59), .w69(w69), .w79(w79), .out0(out0_node0), .out1(out1_node0), .out10_ready(out10_ready_node0), .out11_ready(out11_ready_node0), .z4(z4_node0), .z5(z5_node0), .z6(z6_node0), .z7(z7_node0), .a4(a4_node0), .a5(a5_node0), .a6(a6_node0), .a7(a7_node0));
dnn_top node1(.clk(clk), .x0(x0_node1_ag), .x1(x1_node1_ag), .x2(x2_node1_ag), .x3(x3_node1_ag), .in_ready(in_ready), .w04(w04), .w05(w05), .w06(w06), .w07(w07), .w14(w14), .w15(w15), .w16(w16), .w17(w17), .w24(w24), .w25(w25), .w26(w26), .w27(w27), .w34(w34), .w35(w35), .w36(w36), .w37(w37), .w48(w48), .w58(w58), .w68(w68), .w78(w78), .w49(w49), .w59(w59), .w69(w69), .w79(w79), .out0(out0_node1), .out1(out1_node1), .out10_ready(out10_ready_node1), .out11_ready(out11_ready_node1), .z4(z4_node1), .z5(z5_node1), .z6(z6_node1), .z7(z7_node1), .a4(a4_node1), .a5(a5_node1), .a6(a6_node1), .a7(a7_node1));
dnn_top node2(.clk(clk), .x0(x0_node2_ag), .x1(x1_node2_ag), .x2(x2_node2_ag), .x3(x3_node2_ag), .in_ready(in_ready), .w04(w04), .w05(w05), .w06(w06), .w07(w07), .w14(w14), .w15(w15), .w16(w16), .w17(w17), .w24(w24), .w25(w25), .w26(w26), .w27(w27), .w34(w34), .w35(w35), .w36(w36), .w37(w37), .w48(w48), .w58(w58), .w68(w68), .w78(w78), .w49(w49), .w59(w59), .w69(w69), .w79(w79), .out0(out0_node2), .out1(out1_node2), .out10_ready(out10_ready_node2), .out11_ready(out11_ready_node2), .z4(z4_node2), .z5(z5_node2), .z6(z6_node2), .z7(z7_node2), .a4(a4_node2), .a5(a5_node2), .a6(a6_node2), .a7(a7_node2));
dnn_top node3(.clk(clk), .x0(x0_node3_ag), .x1(x1_node3_ag), .x2(x2_node3_ag), .x3(x3_node3_ag), .in_ready(in_ready), .w04(w04), .w05(w05), .w06(w06), .w07(w07), .w14(w14), .w15(w15), .w16(w16), .w17(w17), .w24(w24), .w25(w25), .w26(w26), .w27(w27), .w34(w34), .w35(w35), .w36(w36), .w37(w37), .w48(w48), .w58(w58), .w68(w68), .w78(w78), .w49(w49), .w59(w59), .w69(w69), .w79(w79), .out0(out0_node3), .out1(out1_node3), .out10_ready(out10_ready_node3), .out11_ready(out11_ready_node3), .z4(z4_node3), .z5(z5_node3), .z6(z6_node3), .z7(z7_node3), .a4(a4_node3), .a5(a5_node3), .a6(a6_node3), .a7(a7_node3));
//Aggregation and Combination
assign a4_node0 = z4_node0 + z4_node1 + z4_node2;
assign a5_node0 = z5_node0 + z5_node1 + z5_node2;
assign a6_node0 = z6_node0 + z6_node1 + z6_node2;
assign a7_node0 = z7_node0 + z7_node1 + z7_node2;
assign a4_node1 = z4_node0 + z4_node1 + z4_node3;
assign a5_node1 = z5_node0 + z5_node1 + z5_node3;
assign a6_node1 = z6_node0 + z6_node1 + z6_node3;
assign a7_node1 = z7_node0 + z7_node1 + z7_node3;
assign a4_node2 = z4_node0 + z4_node3 + z4_node2;
assign a5_node2 = z5_node0 + z5_node3 + z5_node2;
assign a6_node2 = z6_node0 + z6_node3 + z6_node2;
assign a7_node2 = z7_node0 + z7_node3 + z7_node2;
assign a4_node3 = z4_node3 + z4_node1 + z4_node2;
assign a5_node3 = z5_node3 + z5_node1 + z5_node2;
assign a6_node3 = z6_node3 + z6_node1 + z6_node2;
assign a7_node3 = z7_node3 + z7_node1 + z7_node2;
assign x0_node0_ag = x0_node0 + x0_node1 + x0_node2;
assign x1_node0_ag = x1_node0 + x1_node1 + x1_node2;
assign x2_node0_ag = x2_node0 + x2_node1 + x2_node2;
assign x3_node0_ag = x3_node0 + x3_node1 + x3_node2;
assign x0_node1_ag = x0_node0 + x0_node1 + x0_node3;
assign x1_node1_ag = x1_node0 + x1_node1 + x1_node3;
assign x2_node1_ag = x2_node0 + x2_node1 + x2_node3;
assign x3_node1_ag = x3_node0 + x3_node1 + x3_node3;
assign x0_node2_ag = x0_node0 + x0_node3 + x0_node2;
assign x1_node2_ag = x1_node0 + x1_node3 + x1_node2;
assign x2_node2_ag = x2_node0 + x2_node3 + x2_node2;
assign x3_node2_ag = x3_node0 + x3_node3 + x3_node2;
assign x0_node3_ag = x0_node3 + x0_node1 + x0_node2;
assign x1_node3_ag = x1_node3 + x1_node1 + x1_node2;
assign x2_node3_ag = x2_node3 + x2_node1 + x2_node2;
assign x3_node3_ag = x3_node3 + x3_node1 + x3_node2;
endmodule
module tb_top_v1();
reg [4:0] x0_node0, x1_node0, x2_node0, x3_node0;
reg [4:0] x0_node1, x1_node1, x2_node1, x3_node1;
reg [4:0] x0_node2, x1_node2, x2_node2, x3_node2;
reg [4:0] x0_node3, x1_node3, x2_node3, x3_node3;
reg [4:0] w04, w14, w24, w34;
reg [4:0] w05, w15, w25, w35;
reg [4:0] w06, w16, w26, w36;
reg [4:0] w07, w17, w27, w37;
reg [4:0] w48, w58, w68, w78;
reg [4:0] w49, w59, w69, w79;
reg clk;
wire [20:0] out0_node0, out1_node0;
wire [20:0] out0_node1, out1_node1;
wire [20:0] out0_node2, out1_node2;
wire [20:0] out0_node3, out1_node3;
wire out10_ready_node0, out11_ready_node0;
wire out10_ready_node1, out11_ready_node1;
wire out10_ready_node2, out11_ready_node2;
wire out10_ready_node3, out11_ready_node3;
reg in_ready;
// Top module
// Instantiation of top module
// Please replace the instantiation with the top module of your gate level model
// Look for 'test failed' in the message. If there is no such message then your output matches the golden outputs.
top top(.x0_node0(x0_node0), .x1_node0(x1_node0), .x2_node0(x2_node0), .x3_node0(x3_node0),
.x0_node1(x0_node1), .x1_node1(x1_node1), .x2_node1(x2_node1), .x3_node1(x3_node1),
.x0_node2(x0_node2), .x1_node2(x1_node2), .x2_node2(x2_node2), .x3_node2(x3_node2),
.x0_node3(x0_node3), .x1_node3(x1_node3), .x2_node3(x2_node3), .x3_node3(x3_node3),
.w04(w04), .w14(w14), .w24(w24), .w34(w34),
.w05(w05), .w15(w15), .w25(w25), .w35(w35),
.w06(w06), .w16(w16), .w26(w26), .w36(w36),
.w07(w07), .w17(w17), .w27(w27), .w37(w37),
.w48(w48), .w58(w58), .w68(w68), .w78(w78),
.w49(w49), .w59(w59), .w69(w69), .w79(w79),
.out0_node0(out0_node0), .out1_node0(out1_node0),
.out0_node1(out0_node1), .out1_node1(out1_node1),
.out0_node2(out0_node2), .out1_node2(out1_node2),
.out0_node3(out0_node3), .out1_node3(out1_node3),
.in_ready(in_ready),
.out10_ready_node0(out10_ready_node0), .out11_ready_node0(out11_ready_node0),
.out10_ready_node1(out10_ready_node1), .out11_ready_node1(out11_ready_node1),
.out10_ready_node2(out10_ready_node2), .out11_ready_node2(out11_ready_node2),
.out10_ready_node3(out10_ready_node3), .out11_ready_node3(out11_ready_node3),
.clk(clk));
initial begin
clk = 0;
in_ready = 1;
x0_node0 = 5'b0100;
x1_node0 = 5'b0010;
x2_node0 = 5'b0100;
x3_node0 = 5'b0001;
x0_node1 = 5'b0110;
x1_node1 = 5'b0100;
x2_node1 = 5'b0100;
x3_node1 = 5'b0001;
x0_node2 = 5'b1000;
x1_node2 = 5'b0110;
x2_node2 = 5'b0100;
x3_node2 = 5'b0001;
x0_node3 = 5'b0110;
x1_node3 = 5'b0100;
x2_node3 = 5'b0100;
x3_node3 = 5'b0001;
w04 = 5'b00011;
w14 = 5'b00010;
w24 = 5'b01101;
w34 = 5'b11010;
w05 = 5'b10111;
w15 = 5'b00001;
w25 = 5'b11100;
w35 = 5'b01110;
w06 = 5'b00011;
w16 = 5'b00110;
w26 = 5'b10001;
w36 = 5'b01111;
w07 = 5'b01001;
w17 = 5'b10110;
w27 = 5'b01111;
w37 = 5'b10110;
w48 = 5'b00000;
w58 = 5'b11111;
w68 = 5'b00011;
w78 = 5'b10101;
w49 = 5'b10100;
w59 = 5'b10001;
w69 = 5'b10001;
w79 = 5'b00110;
#40
if (out0_node0 == -20'd6358)
$display("-----------out0_node0 is correct-----------------");
else
$display("-----------out0_node0 is incorrect-----------");
if (out1_node0 == -20'd4188)
$display("-----------out1_node0 is correct-----------");
else
$display("-----------out1_node0 is incorrect-----------");
if (out0_node1 == -20'd6309)
$display("-----------out0_node1 is correct-----------------");
else
$display("-----------out0_node1 is incorrect-----------");
if (out1_node1 == -20'd4455)
$display("-----------out1_node1 is correct-----------");
else
$display("-----------out1_node1 is incorrect-----------");
if (out0_node2 == -20'd6287)
$display("-----------out0_node2 is correct-----------------");
else
$display("-----------out0_node2 is incorrect-----------");
if (out1_node2 == -20'd4587)
$display("-----------out1_node2 is correct-----------");
else
$display("-----------out1_node2 is incorrect-----------");
if (out0_node3 == -20'd6309)
$display("-----------out0_node3 is correct-----------------");
else
$display("-----------out0_node3 is incorrect-----------");
if (out1_node3 == -20'd4455)
$display("-----------out1_node3 is correct-----------");
else
$display("-----------out1_node3 is incorrect-----------");
$display("--------------------------------------");
//Min
#40
in_ready = 0;
#40
in_ready = 1;
x0_node0 = -5'd16;
x1_node0 = -5'd16;
x2_node0 = -5'd16;
x3_node0 = -5'd16;
x0_node1 = -5'd16;
x1_node1 = -5'd16;
x2_node1 = -5'd16;
x3_node1 = -5'd16;
x0_node2 = -5'd16;
x1_node2 = -5'd16;
x2_node2 = -5'd16;
x3_node2 = -5'd16;
x0_node3 = -5'd16;
x1_node3 = -5'd16;
x2_node3 = -5'd16;
x3_node3 = -5'd16;
w04 = -5'd16;
w14 = -5'd16;
w24 = -5'd16;
w34 = -5'd16;
w05 = -5'd16;
w15 = -5'd16;
w25 = -5'd16;
w35 = -5'd16;
w06 = -5'd16;
w16 = -5'd16;
w26 = -5'd16;
w36 = -5'd16;
w07 = -5'd16;
w17 = -5'd16;
w27 = -5'd16;
w37 = -5'd16;
w48 = -5'd16;
w58 = -5'd16;
w68 = -5'd16;
w78 = -5'd16;
w49 = -5'd16;
w59 = -5'd16;
w69 = -5'd16;
w79 = -5'd16;
#40
if (out0_node0 == -20'd589824)
$display("-----------out0_node0 is correct-----------------");
else
$display("-----------out0_node0 is incorrect-----------");
if (out1_node0 == -20'd589824)
$display("-----------out1_node0 is correct-----------");
else
$display("-----------out1_node0 is incorrect-----------");
if (out0_node1 == -20'd589824)
$display("-----------out0_node1 is correct-----------------");
else
$display("-----------out0_node1 is incorrect-----------");
if (out1_node1 == -20'd589824)
$display("-----------out1_node1 is correct-----------");
else
$display("-----------out1_node1 is incorrect-----------");
if (out0_node2 == -20'd589824)
$display("-----------out0_node2 is correct-----------------");
else
$display("-----------out0_node2 is incorrect-----------");
if (out1_node2 == -20'd589824)
$display("-----------out1_node2 is correct-----------");
else
$display("-----------out1_node2 is incorrect-----------");
if (out0_node3 == -20'd589824)
$display("-----------out0_node3 is correct-----------------");
else
$display("-----------out0_node3 is incorrect-----------");
if (out1_node3 == -20'd589824)
$display("-----------out1_node3 is correct-----------");
else
$display("-----------out1_node3 is incorrect-----------");
$display("--------------------------------------");
//Max
#40
in_ready = 0;
#40
in_ready = 1;
x0_node0 = 5'd15;
x1_node0 = 5'd15;
x2_node0 = 5'd15;
x3_node0 = 5'd15;
x0_node1 = 5'd15;
x1_node1 = 5'd15;
x2_node1 = 5'd15;
x3_node1 = 5'd15;
x0_node2 = 5'd15;
x1_node2 = 5'd15;
x2_node2 = 5'd15;
x3_node2 = 5'd15;
x0_node3 = 5'd15;
x1_node3 = 5'd15;
x2_node3 = 5'd15;
x3_node3 = 5'd15;
w04 = 5'd15;
w14 = 5'd15;
w24 = 5'd15;
w34 = 5'd15;
w05 = 5'd15;
w15 = 5'd15;
w25 = 5'd15;
w35 = 5'd15;
w06 = 5'd15;
w16 = 5'd15;
w26 = 5'd15;
w36 = 5'd15;
w07 = 5'd15;
w17 = 5'd15;
w27 = 5'd15;
w37 = 5'd15;
w48 = 5'd15;
w58 = 5'd15;
w68 = 5'd15;
w78 = 5'd15;
w49 = 5'd15;
w59 = 5'd15;
w69 = 5'd15;
w79 = 5'd15;
#40
if (out0_node0 == 20'd486000)
$display("-----------out0_node0 is correct-----------------");
else
$display("-----------out0_node0 is incorrect-----------");
if (out1_node0 == 20'd486000)
$display("-----------out1_node0 is correct-----------");
else
$display("-----------out1_node0 is incorrect-----------");
if (out0_node1 == 20'd486000)
$display("-----------out0_node1 is correct-----------------");
else
$display("-----------out0_node1 is incorrect-----------");
if (out1_node1 == 20'd486000)
$display("-----------out1_node1 is correct-----------");
else
$display("-----------out1_node1 is incorrect-----------");
if (out0_node2 == 20'd486000)
$display("-----------out0_node2 is correct-----------------");
else
$display("-----------out0_node2 is incorrect-----------");
if (out1_node2 == 20'd486000)
$display("-----------out1_node2 is correct-----------");
else
$display("-----------out1_node2 is incorrect-----------");
if (out0_node3 == 20'd486000)
$display("-----------out0_node3 is correct-----------------");
else
$display("-----------out0_node3 is incorrect-----------");
if (out1_node3 == 20'd486000)
$display("-----------out1_node3 is correct-----------");
else
$display("-----------out1_node3 is incorrect-----------");
$display("--------------------------------------");
end
always
#1 clk = !clk;
initial
#1000 $finish;
endmodule
完整项目保存在github仓库(https://github.com/Qglddd111/ECE755_gnn),包括SystemVerilog代码、仿真、DC综合、布局布线、DRC/LVS结果。