Using SystemVerilog for FPGA Design中文.docx

上传人:b****8 文档编号:10983512 上传时间:2023-02-24 格式:DOCX 页数:12 大小:21.38KB
下载 相关 举报
Using SystemVerilog for FPGA Design中文.docx_第1页
第1页 / 共12页
Using SystemVerilog for FPGA Design中文.docx_第2页
第2页 / 共12页
Using SystemVerilog for FPGA Design中文.docx_第3页
第3页 / 共12页
Using SystemVerilog for FPGA Design中文.docx_第4页
第4页 / 共12页
Using SystemVerilog for FPGA Design中文.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

Using SystemVerilog for FPGA Design中文.docx

《Using SystemVerilog for FPGA Design中文.docx》由会员分享,可在线阅读,更多相关《Using SystemVerilog for FPGA Design中文.docx(12页珍藏版)》请在冰豆网上搜索。

Using SystemVerilog for FPGA Design中文.docx

UsingSystemVerilogforFPGADesign中文

FPGA设计中使用的SystemVerilog

SystemVerilog中包含了比用于FPGA设计的Verilog语言增强了的许多功能,。

从FPGA供应商和EDA工具供应商的综合工具使SystemVerilog的设计,以比在Verilog更容易理解的风格和较高的抽象层次的描述,加快编码过程和缓和重用。

本文着眼于如何综合的SystemVerilog的可以写在FPGA中常用的各种功能块。

设计围绕一个通用的总线与的多个仲裁masters和多个从机的例子来说明综合的编码方式。

这里描述的一些技术已借由VHDL与SystemVerilog的,而有些则是唯一可行的。

代表逻辑值

标准的4值类型的名为“logic”在SystemVerilog语言中被定义。

这表示对Verilog变量(reg)和wires(0,1,X和Z)隐式地使用的“类型”。

你应该使用这种类型的单比特端口和变量的综合的代码。

多比特端口和变量可以被定义由向量typelogic。

下面的示例中示出的计数器模块与1-比特宽的输入输出端口和一个8位宽的内部变量的一部分。

请注意变量设定从一个单一的连续赋值语句的(见输出qin例子),因此省去了所需的内部电线,将被要求在Verilog,SystemVerilog允许。

modulecounter(inputlogicclk,reset,enable,outputlogicq);

logic[7:

0]count;

...

assignq=count[7];

endmodule:

counter

SystemVerilog允许用户定义新的类型(例如一个特定的长度的logicvector),并给予这些类型的有意义的名称,这可以使代码更容易阅读和增加可重用性的变化可以比一些常见的typedefs而不是许多个别变量声明。

类型定义,因此通常放置内可以导入一个packagethat,到其他模块。

用户定义的类型都支持SystemVerilog的综合工具提供的基本类型是综合的。

以下示例显示了一个包包含一个新的类型,它表示一个8位逻辑向量和packedstruct,由两个4-bit逻辑向量的定义。

声明一个结构被包装的意义,是整个结构的合成工具,酷似一个向量(logic[7:

0]在这种情况下),但可以通过名称访问它的元素在代码中处理。

packagetypes;

typedeflogic[7:

0]wdata_t;

typedefstructpacked{logic[3:

0]data_h;

logic[3:

0]data_l;

}wdata_struct_t;

endpackage:

types

组合逻辑

大多数设计师发现它最容易描述的是组合逻辑功能,而不是一组连续赋值。

SystemVerilog的always_combprocesses就是这样设计的,并自动计算出什么样的信号将触发过程,因此设计人员不必在代码中添加一个敏感列表。

设计师有时候会不经意推断锁存器,当他们写他们的组合逻辑的HDL代码:

always_comb声明告诉锁存器的合成工具,不应该被推断的过程,所以它会发出警告,如果发现任何。

SystemVerilog还包括了像++和break(从C/C++引用的)这样的操作,来简化代码,而使其更容易理解。

下面的代码显示了在我们的例子中设计复用总线主信号的逻辑的一部分。

它使用一个for循环用breakstatement选择具有最高优先级的主信号。

请注意,在SystemVerilog中,一个for循环的循环索引变量可以声明为部分的循环语句(因此它是局部的forloop和不能有其他不期望的作用)。

always_combbegin

//defaultassignmentspreventlatches

addr_a=m_addr[0];

wdata_a=m_wdata[0];

RE_a=m_RE[0];

WE_a=m_WE[0];

//checkallm_gntsignals-startat0incaseonly1master

for(inti=0;i

if(m_gnt[i])begin//lowestindexhaspriority

addr_a=m_addr[i];

wdata_a=m_wdata[i];

RE_a=m_RE[i];

WE_a=m_WE[i];

break;

end

end

end

时序逻辑

寄存器(触发器),一个综合的Verilog设计通常被定义为一个aways块,是敏感的时钟边缘(可能加一个异步复位的reset)。

SystemVerilog增加了的always_ff建设表示时序逻辑的描述过程。

合成工具是必需的检查always_ff过程真的时序逻辑(只有一个定时控制,不堵定时控制语句的变量没有赋值,也将被写入其他进程)。

这是通常使用非阻塞赋值到变量内的always_ffprocess,以避免模拟多个进程所引发的相同的时钟边缘(只是因为它是时钟的always过程中的Verilog)之间的竞争条件。

下面的示例演示计数器模块的过程。

注意,计数器的值没有被写入count++,因为这被视为一个阻塞分配和某些合成工具不允许阻塞和非阻塞的分配到相同的一个进程内的变量。

always_ff@(posedgeclkorposedgereset)

begin

if(reset==1'b1)

count<=0;

else

if(enable==1'b1)count<=count+1'b1;

end

Memories(存储器)

具有多层面的数组可以声明SystemVerilog中。

这些可以有包装尺寸(尺寸在变量名前指定),无包装的尺寸(尺寸在变量名后指定)。

一个二维阵列的逻辑与一个包装尺寸和一个解压缩尺寸可以被合成为一个嵌入式RAM块,如果在其控制的处理相一致的实际RAM阵列被访问。

下面的例子是一个完整的模块,设置模块参数的大小,合成同步RAM。

moduleslave#(parameterasize=8)(interfacebus);

importtypes:

:

*;

wdata_t[(2**asize)-1:

0]memory;

always_ff@(posedgebus.clk)begin

if(bus.WE)

memory[bus.addr]<=bus.wdata;

if(bus.RE)

bus.rdata<=memory[bus.addr];

end

endmodule:

slave

有限状态机

许多FPGA设计包含有限状态机(FSM)。

SystemVerilog中的这些综合的代码编写更灵活,比Verilog中的枚举类型可以用来表示一组的状态。

当一个枚举类型,用于状态寄存器,编译器将检查只有合法的枚举值被分配到状态寄存器。

默认情况下,FPGA综合工具,将选择一个合适的编码方式来表示每个枚举值。

在许多情况下,这将是一热编码在FPGA(实际使用的编码可以通过设置选项中的合成工具控制),以产生最有效的执行。

一个有限状态机编写代码的几种风格的流行(例如,一个单一的主频过程或一颗主频过程加上一个组合的过程)。

以下示例显示了一个单时钟进程FSM在我们的总线主站模块的一部分。

typedefenumlogic[5:

0]{IDLE,REQ,WAITING,READ0,READ1,WRITE0}bus_trans_t;

bus_trans_tbus_trans_state;

always_ff@(posedgebus.clkorposedgebus.reset)begin

//asynchronousreset

if(bus.reset)begin

acount=0;

bus.req<=0;

bus_trans_state<=IDLE;

bus.WE<=0;

bus.RE<=0;

bus.addr<=0;

bus.wdata<=0;

end

elsebegin

case(bus_trans_state)

IDLE:

begin

bus_trans_state<=REQ;

bus.WE<=0;

bus.RE<=0;

end

REQ:

begin

bus.req<=1;

bus_trans_state<=WAITING;

end

WAITING:

begin

if(bus.gnt)begin

acount++;

bus_trans_state<=READ0;

bus.WE<=0;

bus.RE<=1;

bus.addr<={1'b0,acount};

end

end

READ0:

begin

bus_trans_state<=READ1;

bus.WE<=0;

bus.RE<=0;

end

READ1:

begin

//setdatastructfromrdatavector

data=bus.rdata;

//manipulatedatastructmembers

data.data_h={data.data_h[2:

0],data.data_h[3]};

data.data_l={data.data_l[2:

0],data.data_l[3]};

bus_trans_state<=WRITE0;

bus.WE<=1;

bus.RE<=0;

bus.addr<={1'b1,acount};

bus.wdata<=data;

end

WRITE0:

begin

bus.req<=0;//clearrequest

bus_trans_state<=IDLE;

bus.WE<=0;

bus.RE<=0;

end

endcase

end

end

Hierarchy层次

在SystemVerilog的设计创建一个层次结构较Verilog简单主要有两个原因。

第一个原因是,SystemVerilog中,您可以使用变量来连接模块实例的端口,你不必申报线。

这意味着,FPGA设计人员可以停止担心什么时候应使用导线什么时候应使用变量。

一般的规则是,只使用使用变量(除了一些特殊情况下,如三态双向引脚)。

第二个原因是隐式的。

名端口连接。

这些允许的信号连接到指定的端口被省略的.name端口,如果它的名字是完全一样的端口名称(例如,如果端口和信号都CLK)。

它甚至可以使用通配符(.*),而不是端口名称,这意味着每个端口连接的信号具有相同的名称作为端口。

然而,通配符端口连接不喜欢的一些设计师,因为它是很难跟踪在层次结构中,如果端口连接的端口名称中未列出的模块实例。

下面的代码显示了最高级别的基于总线的设计,包括多种隐式和显式的端口connections.The主人和奴隶被连接到interfaceports的。

接口在下一节中解释。

moduletop(inputlogicclk,reset,enable,

outputlogicRE,

outputlogicWE,

outputtypes:

:

addr_taddr,

outputtypes:

:

rdata_trdata,

outputtypes:

:

wdata_twdata);

logicen_data_gen,en_data_gen_b;

intf#(.nmasters

(2),.nslaves

(2))bus(.clk,.reset);

data_genm1(.enable(en_data_gen_b),.bus(bus.master[0].mport));

masterm0(.bus(bus.master[1].mport));

slave#(.asize(7))s0(.bus(bus.slave[0].mport));

slave#(.asize(7))s1(.bus(bus.slave[1].mport));

counterc0(.clk,.reset,.enable,.q(en_data_gen));

assignaddr=bus.addr_a;

assignrdata=bus.rdata_a;

assignwdata=bus.wdata_a;

assignRE=bus.RE_a;

assignWE=bus.WE_a;

assignen_data_gen_b=!

en_data_gen;

endmodule:

top

总线接口和总线架构逻辑

使用SystemVerilogFPGA合成最有吸引力的原因之一是它的代表在一个易于管理的块被称为一个interface与片上总线的复杂的连接和逻辑能力。

不像大多数到目前为止,讨论的主题,这并没有任何同等结构VHDL(2008年版)。

一个SystemVerilog的接口中的一个模块,因为它可以包含端口和过程是相似的,但不同的是模块,它可以连接到一个端口。

代表所有的电线内的片上总线的接口,因此只需要一个端口连接到总线上的每个主机和从机。

此外,modports在接口允许主端口和从机端口有不同的特点。

下面的代码段显示的要点简单的例子,在我们的系统中,表示该仲裁总线的接口。

第一部分显示了需要的时钟和复位总线逻辑接口的端口。

它还显示了如何使用参数的设置大小,内部的信号连接到总线上的主机和从机的数量来体现。

interfaceintf#(parameterintnmasters=2,nslaves=1)

(inputlogicclk,reset);

importtypes:

:

*;

localparammvec_size=$clog2(nmasters);

localparamsvec_size=$clog2(nslaves);

//arbitratedsignals

addr_taddr_a;

wdata_twdata_a;

rdata_trdata_a;

logicRE_a;

logicWE_a;

//signalsto/fromeachmaster

addr_t[mvec_size:

0]m_addr;

wdata_t[mvec_size:

0]m_wdata;

logic[mvec_size:

0]m_req;

logic[mvec_size:

0]m_gnt;

logic[mvec_size:

0]m_RE;

logic[mvec_size:

0]m_WE;

//signalsto/fromeachslave

rdata_t[svec_size:

0]s_rdata;

logic[svec_size:

0]s_RE;

logic[svec_size:

0]s_WE;

接下来,modports需要被定义为将要创建的每个主机和从机。

在第二部分中,我们已经使用了generate语句,使用的nslavesand的nmasters参数来创建正确数量的modports。

在写作的时候,并不是所有的综合工具,支持在一个界面中使用的生成。

使用生成的另一种方法是创建一个接口,与内部信号和modports,支持的最大数量的主机和从机预计。

将被删除任何未连接的信号和modports的优化器自动合成过程中。

在理想的情况下,每个主站和从站被连接到总线的总线(例如,与每个连接的复用的信号相关联的元素)的内部结构的不应该知道。

每主人和奴隶modport的(记得生成将创建数组的modports)可以得到一组通用的端口名称使用“modport表达式”,例如主机可以访问一个名为reqin其modport端口内部连接的接口信号m_req[0]或m_req{1]等

generate

genvarm,s;

for(s=0;s

slave

modportmport(inputclk,reset,

input.addr(addr_a[($left(addr_a)-$clog2(nslaves)):

0]),

output.rdata(s_rdata[s]),

input.wdata(wdata_a),

input.RE(s_RE[s]),

input.WE(s_WE[s]));

end

for(m=0;m

master

modportmport(inputclk,reset,

output.req(m_req[m]),

input.gnt(m_gnt[m]),

output.addr(m_addr[m]),

input.rdata(rdata_a),

output.wdata(m_wdata[m]),

output.RE(m_RE[m]),

output.WE(m_WE[m]));

end

endgenerate

几个进程在我们的接口中指定的仲裁,地址解码和复用总线逻辑主机和从机输出。

下面的过程,在这个例子中定义了简单的仲裁:

它设置了一个位中的m_gnt的寄存器,对应于主已被授予访问总线(主指数最低,有一个请求等待)。

代码复用的主输出的过程已经表明:

地址译码器的逻辑过程是类似的。

always@(posedgeclkorposedgereset)begin

if(reset)begin

m_gnt<=0;

end

elsebegin

if(m_gnt)begin//gntpersistsuntilmasterdropsreq

for(inti=0;i

if(m_gnt[i])m_gnt[i]<=m_req[i];

end

elsebegin//nomastercurrentlyhasgnt

for(inti=0;i

if(m_req[i])begin//masterihaspriority

m_gnt[i]<=1;

break;

end

end

end

end

end

结论

如果您正在使用VerilogFPGA设计,有明显的优势,在更新您的设计流程,而不是使用SystemVerilog(它仍然是向后兼容所有现有的Verilog代码)。

如果你是刚刚起步,它是有道理的,选择的SystemVerilog作为你的第一语言学习FGPA设计。

如果您正在使用VHDL你可能想知道,如果在切换到SystemVerilog的努力可能是有道理的吗?

如果您的FPGA还包含片上复用总线与多个主机和从机,它可能是!

一旦你知道了使用SystemVerilog设计的基本知识,你可能会想看看在测试平台的SystemVerilog语言的功能。

SystemVerilog是一个“大”语言的结构中列出的LRM支持先进的验证方法,使用的技术,如约束随机生成的测试向量,功能覆盖到哪些方面经过全面测试您的设计,断言来发现设计错误,在这方面,SystemVerilog是VHDL或Verilog强大得多,但是那是另一个故事!

本例中使用的SystemVerilog的功能都包含在深入ourSystemVerilog为设计组andComprehensive的SystemVerilog的课程(连同许多其他功能,这里就不讨论了)。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 辩护词

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1