VCS和Verdi 做个简单的联合调试
Synopsys 的 VCS 和 Verdi 是IC设计中使用广泛的开发工具,需要一定的脚本编写能力,新手往往是无法下手,入门比较困难。
因此,写个最简单的使用教程。教程中会用到 Makefile、VCS、Verdi,用Verilog写个简单的ALU,实现简单的实现加减乘除,并编写了testbench进行验证。同时记录一下Makefile脚本。
1. 加法器模块
1 module add ( 2 input wire [7:0] a, 3 input wire [7:0] b, 4 output wire [7:0] out 5 ); 6 7 assign out = a + b; 8 9 endmodule
2. 减法器模块
1 module sub ( 2 input wire [7:0] a, 3 input wire [7:0] b, 4 output wire [7:0] out 5 ); 6 assign out = a - b; 7 endmodule
3. 乘法器模块
1 module mul ( 2 input wire [7:0] a, 3 input wire [7:0] b, 4 output wire [7:0] out 5 ); 6 assign out = a * b; 7 endmodule
4. 除法器模块
1 module div ( 2 input wire [7:0] a, 3 input wire [7:0] b, 4 output wire [7:0] out, 5 output wire [7:0] remainder 6 ); 7 assign out = a / b; 8 assign remainder = a % b; 9 endmodule
5. top模块
1 module alu( 2 input wire clk, 3 input wire rst_n, 4 input wire [2:0] alu_cmd, 5 input wire [7:0] operand_a, 6 input wire [7:0] operand_b, 7 output reg [7:0] result 8 ); 9 10 parameter ADD = 3'd0, 11 SUB = 3'd1, 12 MUL = 3'd2, 13 DIV = 3'd3; 14 15 16 reg [7:0] add_a,add_b,add_data; 17 reg [7:0] sub_a,sub_b,sub_data; 18 reg [7:0] mul_a,mul_b,mul_data; 19 reg [7:0] div_a,div_b,div_data; 20 21 add add_inst(.a(add_a),.b(add_b),.out(add_data) ); 22 sub sub_inst(.a(sub_a),.b(sub_b),.out(sub_data) ); 23 mul mul_inst(.a(mul_a),.b(mul_b),.out(mul_data) ); 24 div div_inst(.a(div_a),.b(div_a),.out(div_data) ); 25 26 always @(posedge clk or negedge rst_n) begin 27 if(rst_n == 1'b0) begin 28 result <= 'd0; 29 end 30 else begin 31 case (alu_cmd) 32 ADD: begin add_a<=operand_a; add_b<=operand_b; result<=add_data; end 33 SUB: begin sub_a<=operand_a; sub_b<=operand_b; result<=sub_data; end 34 MUL: begin mul_a<=operand_a; mul_b<=operand_b; result<=mul_data; end 35 DIV: begin div_a<=operand_a; div_b<=operand_b; result<=div_data; end 36 default: result <= 'd0; 37 endcase 38 end 39 end 40 41 endmodule
6. testbanch模块
1 `timescale 1ns/1ps 2 3 module alu_tb; 4 5 reg clk; 6 reg rst_n; 7 reg [2:0] alu_cmd; 8 reg [7:0] operand_a; 9 reg [7:0] operand_b; 10 wire [7:0] result; 11 12 parameter ADD = 3'd0, 13 SUB = 3'd1, 14 MUL = 3'd2, 15 DIV = 3'd3; 16 17 alu alu_dut ( .clk(clk), 18 .rst_n(rst_n), 19 .alu_cmd(alu_cmd), 20 .operand_a(operand_a), 21 .operand_b(operand_b), 22 .result(result) 23 ); 24 25 always #10 clk = ~clk; 26 27 initial begin 28 rst_n = 0; 29 clk = 0; 30 alu_cmd=ADD; 31 operand_a=0; 32 operand_b=0; 33 #20 34 rst_n = 1; 35 @(posedge clk) 36 operand_a = 10; 37 operand_b = 5; 38 alu_cmd = ADD; 39 @(posedge clk) 40 @(posedge clk) 41 $display("%g + %g = %g ", operand_a,operand_b,result); 42 #30 43 @(posedge clk) 44 operand_a = 22; 45 operand_b = 10; 46 alu_cmd = SUB; 47 @(posedge clk) 48 @(posedge clk) 49 $display("%g - %g = %g ", operand_a,operand_b,result); 50 #30 51 @(posedge clk) 52 operand_a = 10; 53 operand_b = 10; 54 alu_cmd = DIV; 55 @(posedge clk) 56 @(posedge clk) 57 $display("%g / %g = %g ", operand_a,operand_b,result); 58 #30 59 @(posedge clk) 60 operand_a = 2; 61 operand_b = 3; 62 alu_cmd = MUL; 63 @(posedge clk) 64 @(posedge clk) 65 $display("%g * %g = %g ", operand_a,operand_b,result); 66 #30 67 $finish; 68 end 69 70 endmodule
7. Makefile脚本
1 #Makefile for simulink the project 2 #--------------------------------------------------------- 3 4 export TEST_NAME = alu 5 FILE_LIST = $(TEST_NAME).f 6 7 PLATFORM = LINUX64 8 waveform = $(TEST_NAME).fsdb 9 10 vcs_all: clean vcs_compile vcs_simulate 11 12 13 vcs_compile: 14 vcs -sverilog -debug_all -LDFLAGS -rdynamic -full64 \ 15 -P $(Verdi_HOME)/share/PLI/VCS/$(PLATFORM)/novas.tab \ 16 $(Verdi_HOME)/share/PLI/VCS/$(PLATFORM)/pli.a \ 17 -f $(FILE_LIST) \ 18 +vcs+lic+wait \ 19 -l vcs_com.log 20 21 vcs_simulate: 22 ./simv \ 23 -ucli -i dump_fsdb_vcs.tcl \ 24 +fsdb+autoflush \ 25 -l vcs_sim.log 26 36 37 run_verdi: 38 verdi -nologo -sv -f $(FILE_LIST) -ssf $(TEST_NAME).fsdb & 39 40 clean: 41 @rm -rf csrc DVEfiles simv simv.daidir ucli.key novas* VCS* *dat 42
7.1
dump_fsdb_vcs.tcl
1 global env 2 fsdbDumpfile "$env(TEST_NAME).fsdb" 3 fsdbDumpvars 0 "alu_tb" 4 run
8. 运行方法
(1)make vcs_all 这一步先编译上述设计文件,并生成fsdb的波形文件供verdi读入。
(2) make run_verdi 这一步启动verdi并加载波形文件。
9. 结果
verdi 波形
最后波形的结果正确,说明设计的alu满足加减乘除的简单操作。