受verilog-mode的启发,越来越认同代码即注释,注释即代码的思想了。 因此将以注释生成代码的若干脚本汇总在一个工程下,供大家使用。
将工程目录下载于linux工作站后,在~/.vimrc中添加如下的内容:
"you need change the path
command! L :execute '%! /home/ICer/gitee_path/rtl_note_script/src/gen_link.py -f %'
command! LD :execute '%! /home/ICer/gitee_path/rtl_note_script/src -d -f %'
command! U :execute '%! /home/ICer/gitee_path/rtl_note_script/src/auto_unfold.py -f %'
command! UD :execute '%! /home/ICer/gitee_path/rtl_note_script/src/auto_unfold.py -d -f %'
command! AS :execute '%! /home/ICer/gitee_path/rtl_note_script/src/auto_assert.py %'
command! DF :execute '%! /home/ICer/gitee_path/rtl_note_script/src/auto_dff.py -f %'
command! DFD :execute '%! /home/ICer/gitee_path/rtl_note_script/src/auto_dff.py -d -f %'
将其中的路径替换为实际的工程路径。之后可以在vim中直接调用这些脚本,调用方式为在阅览模式下键入冒号+对应的大写字母,之后enter确认即可。
在src/auto_unfold_test目录下有auto_unfold的测试文件。脚本识别的典型注释为:
/* AUTO_UNFOLD
#for i 1..4
wire [15:0] sig#i#;
END */
i为循环变量,1和4为上下界均为包含模式。在键入:U后会展开为:
/* AUTO_UNFOLD
#for i 1..4
wire [15:0] sig#i#;
END */
//AUTO_UNFOLD_START
wire [15:0] sig1;
wire [15:0] sig2;
wire [15:0] sig3;
wire [15:0] sig4;
//AUTO_UNFOLD_END
键入:UD后会删除所有//AUTO_UNFOLD_START ~ //AUTO_UNFOLD_END之间的生成内容,恢复原本的文本内容。
上下界可以从大到小,从小到大,也可以一样:
/* AUTO_UNFOLD
#for i 1..1
wire [15:0] sig#i#;
END */
//AUTO_UNFOLD_START
wire [15:0] sig1;
//AUTO_UNFOLD_END
/* AUTO_UNFOLD
#for i 5..1
wire [15:0] sig#i#;
END */
//AUTO_UNFOLD_START
wire [15:0] sig5;
wire [15:0] sig4;
wire [15:0] sig3;
wire [15:0] sig2;
wire [15:0] sig1;
//AUTO_UNFOLD_END
支持有多行的生成项:
/* AUTO_UNFOLD
#for i 5..1
wire [15:0] sig#i#;
wire [15:0] reg#i#;
END */
//AUTO_UNFOLD_START
wire [15:0] sig5;
wire [15:0] reg5;
wire [15:0] sig4;
wire [15:0] reg4;
wire [15:0] sig3;
wire [15:0] reg3;
wire [15:0] sig2;
wire [15:0] reg2;
wire [15:0] sig1;
wire [15:0] reg1;
//AUTO_UNFOLD_END
支持多个循环变量嵌套,嵌套时先循环上方的变量:
/* AUTO_UNFOLD
#for i 2..1
#for j 5..5
#for k 4..3
wire [15:0] k#k#_sig#j#_sub#i#;
END */
//AUTO_UNFOLD_START
wire [15:0] k4_sig5_sub2;
wire [15:0] k4_sig5_sub1;
wire [15:0] k3_sig5_sub2;
wire [15:0] k3_sig5_sub1;
//AUTO_UNFOLD_END
支持localparam,但是要求localparam的格式很固定,只能是下面这两种。因为localparam是本地的参数,原则上不能被修改只能是一个固定的值。如果有运算式或者和parameter关联了,脚本无法解析。
参数只能在出现在两个位置:循环里和后面提到的IF选择中:
localparam LOOP_I_MIN = 3, LOOP_I_MAX = 5;
localparam LOOP_J_MIN = 2;
/* AUTO_UNFOLD
#for i LOOP_I_MIN..LOOP_I_MAX
#for j LOOP_J_MIN..5
wire [15:0] sig#j#_sub#i#;
END */
//AUTO_UNFOLD_START
wire [15:0] sig2_sub3;
wire [15:0] sig2_sub4;
wire [15:0] sig2_sub5;
wire [15:0] sig3_sub3;
wire [15:0] sig3_sub4;
wire [15:0] sig3_sub5;
wire [15:0] sig4_sub3;
wire [15:0] sig4_sub4;
wire [15:0] sig4_sub5;
wire [15:0] sig5_sub3;
wire [15:0] sig5_sub4;
wire [15:0] sig5_sub5;
//AUTO_UNFOLD_END
支持循环变量的四则和取模运算:
/* AUTO_UNFOLD
#for i LOOP_I_MIN..LOOP_I_MAX
#for j LOOP_J_MIN..5
wire [15:0] sig#i%j#_#j#_sub#i#;
END */
//AUTO_UNFOLD_START
wire [15:0] sig1_2_sub3;
wire [15:0] sig0_2_sub4;
wire [15:0] sig1_2_sub5;
wire [15:0] sig0_3_sub3;
wire [15:0] sig1_3_sub4;
wire [15:0] sig2_3_sub5;
wire [15:0] sig3_4_sub3;
wire [15:0] sig0_4_sub4;
wire [15:0] sig1_4_sub5;
wire [15:0] sig3_5_sub3;
wire [15:0] sig4_5_sub4;
wire [15:0] sig0_5_sub5;
//AUTO_UNFOLD_END
支持生成行里带有条件,但是只支持if一种,不支持elseif和else:
/* AUTO_UNFOLD
#for i 3..2
#for j 0..0
#for k 5..4
IF(#i==3 and k==4#)reg [15:0] sig_k#k#_j#j#_i#i#;
END */
//AUTO_UNFOLD_START
reg [15:0] sig_k4_j0_i3;
//AUTO_UNFOLD_END
IF中带有参数的情况,注意SEL_NUM_SUB1不能是SEL_NUM -1,脚本识别不了参数里的运算:
localparam SEL_NUM = 32;
localparam SEL_NUM_SUB1 = 31;
/* AUTO_UNFOLD
#for i 0..SEL_NUM_SUB1
IF(#i==0#)assign out_sig = (sel == 3'd#i#) ? in_sig#i# :
IF(#i>0 and i<SEL_NUM_SUB1#) (sel == 3'd#i#) ? in_sig#i# :
IF(#i==SEL_NUM_SUB1#) in_sig#i# ;
END */
//AUTO_UNFOLD_START
assign out_sig = (sel == 3'd0) ? in_sig0 :
(sel == 3'd1) ? in_sig1 :
(sel == 3'd2) ? in_sig2 :
(sel == 3'd3) ? in_sig3 :
(sel == 3'd4) ? in_sig4 :
(sel == 3'd5) ? in_sig5 :
(sel == 3'd6) ? in_sig6 :
(sel == 3'd7) ? in_sig7 :
(sel == 3'd8) ? in_sig8 :
(sel == 3'd9) ? in_sig9 :
(sel == 3'd10) ? in_sig10 :
(sel == 3'd11) ? in_sig11 :
(sel == 3'd12) ? in_sig12 :
(sel == 3'd13) ? in_sig13 :
(sel == 3'd14) ? in_sig14 :
(sel == 3'd15) ? in_sig15 :
(sel == 3'd16) ? in_sig16 :
(sel == 3'd17) ? in_sig17 :
(sel == 3'd18) ? in_sig18 :
(sel == 3'd19) ? in_sig19 :
(sel == 3'd20) ? in_sig20 :
(sel == 3'd21) ? in_sig21 :
(sel == 3'd22) ? in_sig22 :
(sel == 3'd23) ? in_sig23 :
(sel == 3'd24) ? in_sig24 :
(sel == 3'd25) ? in_sig25 :
(sel == 3'd26) ? in_sig26 :
(sel == 3'd27) ? in_sig27 :
(sel == 3'd28) ? in_sig28 :
(sel == 3'd29) ? in_sig29 :
(sel == 3'd30) ? in_sig30 :
in_sig31 ;
//AUTO_UNFOLD_END
在项目中的实际操作场景:
/* AUTO_UNFOLD
#for i 0..31
wire [DATA_W -1:0]common_reg_q#i#;
IF(#i>0#)tyrc_dffre #(.WD(DATA_W)) u_common_reg#i#(.clk(clk), .rst_n(rst_n), .d(d), .en(en[#i#]), .q(reg_q#i#));
IF(#i==0#)assign common_reg_q#i# = {DATA_W{1'b0}};
END */
//AUTO_UNFOLD_START
wire [DATA_W -1:0]common_reg_q0;
assign common_reg_q0 = {DATA_W{1'b0}};
wire [DATA_W -1:0]common_reg_q1;
tyrc_dffre #(.WD(DATA_W)) u_common_reg1(.clk(clk), .rst_n(rst_n), .d(d), .en(en[1]), .q(reg_q1));
wire [DATA_W -1:0]common_reg_q2;
tyrc_dffre #(.WD(DATA_W)) u_common_reg2(.clk(clk), .rst_n(rst_n), .d(d), .en(en[2]), .q(reg_q2));
wire [DATA_W -1:0]common_reg_q3;
tyrc_dffre #(.WD(DATA_W)) u_common_reg3(.clk(clk), .rst_n(rst_n), .d(d), .en(en[3]), .q(reg_q3));
wire [DATA_W -1:0]common_reg_q4;
tyrc_dffre #(.WD(DATA_W)) u_common_reg4(.clk(clk), .rst_n(rst_n), .d(d), .en(en[4]), .q(reg_q4));
wire [DATA_W -1:0]common_reg_q5;
tyrc_dffre #(.WD(DATA_W)) u_common_reg5(.clk(clk), .rst_n(rst_n), .d(d), .en(en[5]), .q(reg_q5));
wire [DATA_W -1:0]common_reg_q6;
tyrc_dffre #(.WD(DATA_W)) u_common_reg6(.clk(clk), .rst_n(rst_n), .d(d), .en(en[6]), .q(reg_q6));
wire [DATA_W -1:0]common_reg_q7;
tyrc_dffre #(.WD(DATA_W)) u_common_reg7(.clk(clk), .rst_n(rst_n), .d(d), .en(en[7]), .q(reg_q7));
wire [DATA_W -1:0]common_reg_q8;
tyrc_dffre #(.WD(DATA_W)) u_common_reg8(.clk(clk), .rst_n(rst_n), .d(d), .en(en[8]), .q(reg_q8));
wire [DATA_W -1:0]common_reg_q9;
tyrc_dffre #(.WD(DATA_W)) u_common_reg9(.clk(clk), .rst_n(rst_n), .d(d), .en(en[9]), .q(reg_q9));
wire [DATA_W -1:0]common_reg_q10;
tyrc_dffre #(.WD(DATA_W)) u_common_reg10(.clk(clk), .rst_n(rst_n), .d(d), .en(en[10]), .q(reg_q10));
wire [DATA_W -1:0]common_reg_q11;
tyrc_dffre #(.WD(DATA_W)) u_common_reg11(.clk(clk), .rst_n(rst_n), .d(d), .en(en[11]), .q(reg_q11));
wire [DATA_W -1:0]common_reg_q12;
tyrc_dffre #(.WD(DATA_W)) u_common_reg12(.clk(clk), .rst_n(rst_n), .d(d), .en(en[12]), .q(reg_q12));
wire [DATA_W -1:0]common_reg_q13;
tyrc_dffre #(.WD(DATA_W)) u_common_reg13(.clk(clk), .rst_n(rst_n), .d(d), .en(en[13]), .q(reg_q13));
wire [DATA_W -1:0]common_reg_q14;
tyrc_dffre #(.WD(DATA_W)) u_common_reg14(.clk(clk), .rst_n(rst_n), .d(d), .en(en[14]), .q(reg_q14));
wire [DATA_W -1:0]common_reg_q15;
tyrc_dffre #(.WD(DATA_W)) u_common_reg15(.clk(clk), .rst_n(rst_n), .d(d), .en(en[15]), .q(reg_q15));
wire [DATA_W -1:0]common_reg_q16;
tyrc_dffre #(.WD(DATA_W)) u_common_reg16(.clk(clk), .rst_n(rst_n), .d(d), .en(en[16]), .q(reg_q16));
wire [DATA_W -1:0]common_reg_q17;
tyrc_dffre #(.WD(DATA_W)) u_common_reg17(.clk(clk), .rst_n(rst_n), .d(d), .en(en[17]), .q(reg_q17));
wire [DATA_W -1:0]common_reg_q18;
tyrc_dffre #(.WD(DATA_W)) u_common_reg18(.clk(clk), .rst_n(rst_n), .d(d), .en(en[18]), .q(reg_q18));
wire [DATA_W -1:0]common_reg_q19;
tyrc_dffre #(.WD(DATA_W)) u_common_reg19(.clk(clk), .rst_n(rst_n), .d(d), .en(en[19]), .q(reg_q19));
wire [DATA_W -1:0]common_reg_q20;
tyrc_dffre #(.WD(DATA_W)) u_common_reg20(.clk(clk), .rst_n(rst_n), .d(d), .en(en[20]), .q(reg_q20));
wire [DATA_W -1:0]common_reg_q21;
tyrc_dffre #(.WD(DATA_W)) u_common_reg21(.clk(clk), .rst_n(rst_n), .d(d), .en(en[21]), .q(reg_q21));
wire [DATA_W -1:0]common_reg_q22;
tyrc_dffre #(.WD(DATA_W)) u_common_reg22(.clk(clk), .rst_n(rst_n), .d(d), .en(en[22]), .q(reg_q22));
wire [DATA_W -1:0]common_reg_q23;
tyrc_dffre #(.WD(DATA_W)) u_common_reg23(.clk(clk), .rst_n(rst_n), .d(d), .en(en[23]), .q(reg_q23));
wire [DATA_W -1:0]common_reg_q24;
tyrc_dffre #(.WD(DATA_W)) u_common_reg24(.clk(clk), .rst_n(rst_n), .d(d), .en(en[24]), .q(reg_q24));
wire [DATA_W -1:0]common_reg_q25;
tyrc_dffre #(.WD(DATA_W)) u_common_reg25(.clk(clk), .rst_n(rst_n), .d(d), .en(en[25]), .q(reg_q25));
wire [DATA_W -1:0]common_reg_q26;
tyrc_dffre #(.WD(DATA_W)) u_common_reg26(.clk(clk), .rst_n(rst_n), .d(d), .en(en[26]), .q(reg_q26));
wire [DATA_W -1:0]common_reg_q27;
tyrc_dffre #(.WD(DATA_W)) u_common_reg27(.clk(clk), .rst_n(rst_n), .d(d), .en(en[27]), .q(reg_q27));
wire [DATA_W -1:0]common_reg_q28;
tyrc_dffre #(.WD(DATA_W)) u_common_reg28(.clk(clk), .rst_n(rst_n), .d(d), .en(en[28]), .q(reg_q28));
wire [DATA_W -1:0]common_reg_q29;
tyrc_dffre #(.WD(DATA_W)) u_common_reg29(.clk(clk), .rst_n(rst_n), .d(d), .en(en[29]), .q(reg_q29));
wire [DATA_W -1:0]common_reg_q30;
tyrc_dffre #(.WD(DATA_W)) u_common_reg30(.clk(clk), .rst_n(rst_n), .d(d), .en(en[30]), .q(reg_q30));
wire [DATA_W -1:0]common_reg_q31;
tyrc_dffre #(.WD(DATA_W)) u_common_reg31(.clk(clk), .rst_n(rst_n), .d(d), .en(en[31]), .q(reg_q31));
//AUTO_UNFOLD_END
/* AUTO_UNFOLD
#for i 0..31
IF(#i==0#)assign qa = (rna == 5'd#i#) ? common_reg_q#i# :
IF(#i>0 and i<31#) (rna == 5'd#i#) ? common_reg_q#i# :
IF(#i==31#) common_reg_q#i# ;
END */
//AUTO_UNFOLD_START
assign qa = (rna == 5'd0) ? common_reg_q0 :
(rna == 5'd1) ? common_reg_q1 :
(rna == 5'd2) ? common_reg_q2 :
(rna == 5'd3) ? common_reg_q3 :
(rna == 5'd4) ? common_reg_q4 :
(rna == 5'd5) ? common_reg_q5 :
(rna == 5'd6) ? common_reg_q6 :
(rna == 5'd7) ? common_reg_q7 :
(rna == 5'd8) ? common_reg_q8 :
(rna == 5'd9) ? common_reg_q9 :
(rna == 5'd10) ? common_reg_q10 :
(rna == 5'd11) ? common_reg_q11 :
(rna == 5'd12) ? common_reg_q12 :
(rna == 5'd13) ? common_reg_q13 :
(rna == 5'd14) ? common_reg_q14 :
(rna == 5'd15) ? common_reg_q15 :
(rna == 5'd16) ? common_reg_q16 :
(rna == 5'd17) ? common_reg_q17 :
(rna == 5'd18) ? common_reg_q18 :
(rna == 5'd19) ? common_reg_q19 :
(rna == 5'd20) ? common_reg_q20 :
(rna == 5'd21) ? common_reg_q21 :
(rna == 5'd22) ? common_reg_q22 :
(rna == 5'd23) ? common_reg_q23 :
(rna == 5'd24) ? common_reg_q24 :
(rna == 5'd25) ? common_reg_q25 :
(rna == 5'd26) ? common_reg_q26 :
(rna == 5'd27) ? common_reg_q27 :
(rna == 5'd28) ? common_reg_q28 :
(rna == 5'd29) ? common_reg_q29 :
(rna == 5'd30) ? common_reg_q30 :
common_reg_q31 ;
//AUTO_UNFOLD_END
/* AUTO_UNFOLD
#for i 0..31
IF(#i==0#)assign qb = (rnb == 5'd#i#) ? common_reg_q#i# :
IF(#i>0 and i<31#) (rnb == 5'd#i#) ? common_reg_q#i# :
IF(#i==31#) common_reg_q#i# ;
END */
//AUTO_UNFOLD_START
assign qb = (rnb == 5'd0) ? common_reg_q0 :
(rnb == 5'd1) ? common_reg_q1 :
(rnb == 5'd2) ? common_reg_q2 :
(rnb == 5'd3) ? common_reg_q3 :
(rnb == 5'd4) ? common_reg_q4 :
(rnb == 5'd5) ? common_reg_q5 :
(rnb == 5'd6) ? common_reg_q6 :
(rnb == 5'd7) ? common_reg_q7 :
(rnb == 5'd8) ? common_reg_q8 :
(rnb == 5'd9) ? common_reg_q9 :
(rnb == 5'd10) ? common_reg_q10 :
(rnb == 5'd11) ? common_reg_q11 :
(rnb == 5'd12) ? common_reg_q12 :
(rnb == 5'd13) ? common_reg_q13 :
(rnb == 5'd14) ? common_reg_q14 :
(rnb == 5'd15) ? common_reg_q15 :
(rnb == 5'd16) ? common_reg_q16 :
(rnb == 5'd17) ? common_reg_q17 :
(rnb == 5'd18) ? common_reg_q18 :
(rnb == 5'd19) ? common_reg_q19 :
(rnb == 5'd20) ? common_reg_q20 :
(rnb == 5'd21) ? common_reg_q21 :
(rnb == 5'd22) ? common_reg_q22 :
(rnb == 5'd23) ? common_reg_q23 :
(rnb == 5'd24) ? common_reg_q24 :
(rnb == 5'd25) ? common_reg_q25 :
(rnb == 5'd26) ? common_reg_q26 :
(rnb == 5'd27) ? common_reg_q27 :
(rnb == 5'd28) ? common_reg_q28 :
(rnb == 5'd29) ? common_reg_q29 :
(rnb == 5'd30) ? common_reg_q30 :
common_reg_q31 ;
//AUTO_UNFOLD_END
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。