ECE755_gnn图神经网络(附完整工程)

ECE755_gnn图神经网络(附完整工程)

  • ECE755
  • 课程要求
  • 任务1完成:
    • 题目要求
    • MS1代码:
    • 仿真
  • 任务二完成
    • 题目要求
    • MS2代码:
    • 仿真
  • 总结

ECE755

ECE 755_sp23是加拿大渥太华大学(University of Ottawa)计算机工程系(School of Electrical Engineering and Computer Science)的一个研究生课程,涵盖了图神经网络(Graph Neural Networks)及其应用的基本概念和原理。该课程的主要目标是介绍最新的图神经网络模型,并探讨它们在处理图形数据、社交网络、推荐系统、自然语言处理等领域中的实际应用。该课程强调深入理解GNN模型的数学原理,并通过实验和项目作业来帮助学生巩固所学知识并提高实践技能。其中包括用Verilog实现gnn的部分。

课程要求

  以下是ECE 755_sp23的实验要求:

  • Milestone 1: Write the Verilog code for a deep neural network (DNN) that will be embedded into a graph.
    任务1:编写将嵌入到图中的深度神经网络(DNN)的Verilog代码。
  • Milestone 2: Write the Verilog code for a GNN that embeds the DNN from MS-1.
    任务2:为嵌入MS-1的DNN的GNN编写Verilog代码。
  • Milestone 3: Synthesize your design using Design Compiler and verify the synthesized netlist.
    任务3:使用DC进行设计综合,并验证综合网表。
  • Milestone 4: Perform automatic place-and-route (APR).
    任务4:执行自动位置和路线(APR)。
  • Milestone 5: Post-APR-export GDS, import the GDS into Virtuoso layout, and perform DRC/LVS on the final layout of the design.
    任务5:APR后导出GDS,将GDS导入Virtuoso布局,并对设计的最终布局执行DRC/LVS。
  • Milestone 6: Make power/performance estimations.
    任务6:进行功率/性能评估。

任务1完成:

题目要求

ECE755_gnn图神经网络(附完整工程)_第1张图片
  MS-1的目标是使用HDL (Verilog/System Verilog)实现嵌入在每个节点中的神经网络的推理(图2)。假设所有输入为5位,输出值为17位,输入和输出都是有符号数。顶级模块应该具有以下模块定义和输入/输出端口:
ECE755_gnn图神经网络(附完整工程)_第2张图片
ECE755_gnn图神经网络(附完整工程)_第3张图片

MS1代码:

  1. layer_1.sv:
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

  1. layer_2.sv:
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

  1. Relu.sv:
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

  1. top.sv:
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

仿真情况如下:
ECE755_gnn图神经网络(附完整工程)_第4张图片

任务二完成

题目要求

目标是在Verilog中实现GNN的推理。GNN的顶层模块应该具有以下模块定义和输入/输出端口。
ECE755_gnn图神经网络(附完整工程)_第5张图片
ECE755_gnn图神经网络(附完整工程)_第6张图片
ECE755_gnn图神经网络(附完整工程)_第7张图片

MS2代码:

除了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

仿真结果:
ECE755_gnn图神经网络(附完整工程)_第8张图片

总结

  完整项目保存在github仓库(https://github.com/Qglddd111/ECE755_gnn),包括SystemVerilog代码、仿真、DC综合、布局布线、DRC/LVS结果。

你可能感兴趣的:(GNN,神经网络,人工智能,深度学习,fpga)