AxiTdl
Axi
axi是一个 axi4 拓展库,它使用的是删减版的AXI4协议,使用systemverilog开发,除此外我还拓展了AXI4的一些信号。
axi hdl 所在路径可以如下Ruby 脚本获取
require 'axi_tdl'
AxiTdl::AXI_PATH
其他
此库还包含一个简单的接口定义, 接口信号只有 valid
, ready
, 和 data
. 对于一些轻量设计很有帮助。
tdl 是什么?
tdl 是一种硬件构造语言, 和chisel类似, 但是更加有趣, 他是一种基于Ruby的DSL. 最终它会编译输出systemverilog。 tdl也是基于axi库做的设计。这两部分都包含这此gem包中。
tdl 能做什么?
使用tdl做设计开发, 语法类似systemverilog,这样更亲切。不止于此, tdl加入了大量的验证语法。tdl创建的初衷就是为了快速构建逻辑系统
, 这就是tdl和其他硬件构造语言最大的区别。
安装
Gemfile中添加:
gem 'axi_tdl'
然后执行:
$ bundle
或则通过gem命令安装:
$ gem install axi_tdl
代码示例
1. 定义模块
在当前tdl所在的路径创建一个systemverilog模块文件,模块名为 test_module
.
TdlBuild.test_module(__dir__) do
## Other code
end
输出的systemverilog 文件如下:
`timescale 1ns/1ps
module test_module(
);
endmodule
2. 端口
TdlBuild.test_module(__dir__) do
input.clock - 'clock'
input.reset('low') - 'rst_n'
input - 'd0'
input[32] - 'd32'
output[16] - 'o16'
output.logic[8] - 'o8'
output.logic - 'o1'
end
module test_module (
input clock,
input rst_n,
input d0,
input [31:0] d32,
output [15:0] o16,
output logic[7:0] o8,
output logic o1
);
endmodule
3. 接口
TdlBuild.test_interface(__dir__) do
input.clock - 'clock'
input.reset('low') - 'rst_n'
input - 'd0'
input[32] - 'd32'
output[16] - 'o16'
output.logic[8] - 'o8'
output.logic - 'o1'
port.axis.slaver - 'axis_in'
port.axis.master - 'axis_out'
port.axis.mirror - 'axis_mirror'
port.data_c.master - 'intf_data_inf'
port.axi4.slaver - 'taxi4_inf'
end
module test_module (
input clock,
input rst_n,
input d0,
input [31:0] d32,
output [15:0] o16,
output logic[7:0] o8,
output logic o1,
axi_stream_inf.slaver axis_in,
axi_stream_inf.master axis_out,
axi_stream_inf.mirror axis_mirror,
data_inf_c.master intf_data_inf,
axi_inf.slaver taxi4_inf
);
end
4. always assign
TdlBuild.test_module(__dir__) do
input.clock - 'clock'
input.reset('low') - 'rst_n'
input - 'd0'
input[32] - 'd32'
output[16] - 'o16'
output.logic[8] - 'o8'
output.logic - 'o1'
port.axis.slaver - 'axis_in'
port.axis.master - 'axis_out'
port.axis.mirror - 'axis_mirror'
port.data_c.master - 'intf_data_inf'
port.axi4.slaver - 'taxi4_inf'
always_ff(posedge: clock,negedge: rst_n) do
IF ~rst_n do
o16 <= 0.A
end
ELSE do
IF d0 do
o16 <= 1.A
end
ELSE do
o16 <= o16 + 1.b1
end
end
end
always_comb do
o8 <= d32[7,0]
end
Assign do
o1 <= 1.b0
end
end
module test_module (
input clock,
input rst_n,
input d0,
input [31:0] d32,
output [15:0] o16,
output logic[7:0] o8,
output logic o1,
axi_stream_inf.slaver axis_in,
axi_stream_inf.master axis_out,
axi_stream_inf.mirror axis_mirror,
data_inf_c.master intf_data_inf,
axi_inf.slaver taxi4_inf
);
always_ff@(posedge clock,negedge rst_n) begin
if(~rst_n)begin
o16 <= '0;
end
else begin
if(d0)begin
o16 <= '1;
end
else begin
o16 <= ( o16+1'b1);
end
end
end
always_comb begin
o8 = d32[7:0];
end
assign o1 = 1'b0;
endmodule
5. generate
TdlBuild.test_generate(__dir__) do
parameter.NUM 8
input[8] - 'ain'
output[8] - 'bout'
input[param.NUM,6] - 'cin'
output[6,param.NUM] - 'dout'
input[param.NUM] - 'ein'
output[param.NUM] - 'fout'
generate(8) do |kk|
Assign do
bout[kk] <= ain[7-kk]
end
end
generate(param.NUM) do |cc|
IF cc < 4 do
Assign do
dout[cc] <= cin[cc]
end
end
ELSE do
Assign do
dout[cc] <= cin[cc] + cc
end
end
end
generate(param.NUM,6) do |ii,gg|
Assign do
fout[ii][gg] <= ein[gg][ii]
end
end
end
module test_generate #(
parameter NUM = 8
)(
input [7:0] ain,
output [7:0] bout,
input [5:0] cin [NUM-1:0],
output [ NUM-1:0] dout [6-1:0],
input [ NUM-1:0] ein,
output [ NUM-1:0] fout
);
generate
for(genvar KK0=0;KK0 < 8;KK0++)begin
assign bout[ KK0] = ain[ 7-( KK0)];
end
endgenerate
generate
for(genvar KK0=0;KK0 < NUM;KK0++)begin
if( KK0<4)begin
assign dout[ KK0] = cin[ KK0];
end
else begin
assign dout[ KK0] = ( cin[ KK0]+( KK0));
end
end
endgenerate
generate
for(genvar KK0=0;KK0 < NUM;KK0++)begin
for(genvar KK1=0;KK1 < 6;KK1++)begin
assign fout[ KK0][ KK1] = ein[ KK1][ KK0];
end
end
endgenerate
endmodule
6. 合并 logic
TdlBuild.test_logic_combin(__dir__) do
logic[7] - 'a0'
logic[5] - 'a1'
logic[9] - 'a2'
logic[9+5+7] - 'ca'
logic[2,8] - 'b0'
logic[16] - 'b1'
logic[32] - 'cb'
logic[1,8] - 'c0'
logic[3,8] - 'c1'
logic[2,16] - 'cc'
Assign do
ca <= logic_bind_(a0, a1, a2)
cb <= self.>>(b1, b0)
cc <= self.<<(c0, c1)
end
end
module test_logic_combin ();
logic [7-1:0] a0 ;
logic [5-1:0] a1 ;
logic [9-1:0] a2 ;
logic [21-1:0] ca ;
logic [8-1:0] b0[2-1:0] ;
logic [16-1:0] b1 ;
logic [32-1:0] cb ;
logic [8-1:0] c0[1-1:0] ;
logic [8-1:0] c1[3-1:0] ;
logic [16-1:0] cc[2-1:0] ;
assign ca = {a0,a1,a2};
assign cb = {>>{b1,b0}};
assign cc = {<<{c0,c1}};
endmodule