DPI进阶

首先认识一下,压缩数组和非压缩数组

压缩数组(Packed arrays)

对于某些数据类型,你可能希望既可以访问整个值,也可以将其分成更小的元素。 例如,你可能有一个32位寄存器,有时你希望将其视为四个8位值,而在其他时候则视为单个无符号值。 压缩数组被视为数组和单个值。 与非压缩的数组不同,它存储为一组连续的没有未使用空间的位。可以方便地将其作为数组元素进行访问。

压缩数组:在数据类型标识符名称之前声明的维度
bit [7:0] p; // packed array of scalar bit types
bit [3:0] [7:0] bytes // 4 bytes packed into 32-bits

压缩数组仅可以有单bit数据类型组成(bit, logic, reg)

具有预定义宽度的整数类型不能声明为带维度的压缩数组。 这些类型是byte,shortint,int,longint,integer和time。 虽然是具有预定义宽度n的整数类型,它不是一个打包数组,但其自身是可以分解为子字段的,就像它是一个具有单个[n-1:0]维度的压缩数组类型。
byte c2; // same as bit signed [7:0] c2;
integer i1; // same as logic signed [31:0] i1;

非压缩数组(Unpacked arrays)

非压缩数组可以由任何数据类型组成。每个固定大小的维度应由地址范围(例如[1:1024])或单个正数来表示,以指定固定大小的非压缩数组的大小,如C中所示。换句话说,[size]变为与[0:size-1]相同。
非压缩数组:在数据类型标识符名称后声明的维度
bit u [7:0];
int Array[0:7][0:31]; // array declaration using ranges
int Array[8][32]; // array declaration using sizes

SV 索引 [min:max] -> C端数组索引从0开始
SV: a[1:7] -> C: a[7]
SV: a[1] -> C: a[0], SV a[7] -> C: a[6]

SV压缩数组被当做一维数组对待
SV端 a[l][m][n]中的一个bit转换到 C端 a[n+mk+lj*k]
bit[5:2]a; a[5]=1 a[4]=0 a[3]=1 a[2]=0; -> C: a=10

所有数据类型最终都等同于最多32位的压缩数组
SV byte -> C int,只使用低8位
C char数组无法映射到SV byte类型的非压缩数组

混合压缩和非压缩的数组

bit [3:0] Bytes [0:2] [0:5]

SV_PACKED_DATA_NELEMS(width)

C marco SV_PACKED_DATA_NELEMS(width)从位转换为元素数
在bit和word之间转换
SV_PACKED_DATA_NELEMS(40)将40位转换为2个32位的字

#include "svdpi.h"

void packet_C(const svLogicVecVal* packet) {
   const unsigned  elements=SV_PACKED_DATA_NELEMS(128);
   svLogicVecVal mem[elements];
 
   memcpy(mem,packet,sizeof(mem));
   io_printf(“C: data from SV side\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
   for (unsigned i=0;i< elements;i++){
      io_printf("mem[%2d]={%4x,%4x}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n",i,mem[i].aval,mem[i].bval);
 
   }    
}
module test;
 
import "DPI-C" function void packet_C( input logic [127:0]);
 
   logic [127:0] packet;
   initial begin
      packet=128'h1234_5678_aaaa_bbbb_cccc_dddd_eeee_ffff;
      $display(“SV: data sent to C side: %x",packet);
      packet_C(packet);
   end
 
endmodule

bit和logic标量和矢量的使用

在svdpi.h的头文件中,有如下自定义类型声明:

typedef uint8_t svScalar;
typedef svScalar svBit; /* scalar */
typedef svScalar svLogic; /* scalar */

typedef unsigned int svBitVecVal;

Typedef struct{
     unsigned int aval;
     unsigned int bval;
} svLogicVecVal;

具体SV端和C端的对应关系如下:
SV bit -> C bit, SV bit[n:0] -> C svBitVecVal
SV logic -> C svLogic,SV logic[n:0] -> C svLogicVecVal

bit是二值逻辑,SV端和C端的数值是一样的。但是logic是四值逻辑,SV端的值怎么和C端的值对应起来呢?请看下表:

4-state valuebvalaval
000
101
z10
x11
#include <stdio.h> 
#include <svdpi.h> 

void show(svLogic a){ 
	if(a == 0) 
		printf(" a is 0 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
	else if(a == 1) 
		printf(" a is 1 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
	else if(a == 2) 
		printf(" a is x \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
	else if(a == 3)
		printf(" a is z \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");

} 
program main;
logic a;
import "DPI-C" function void show(logic a); 
initial begin
	a = 1'b0;
	show(a);
	a = 1'b1;
	show(a);
	a = 1'bX;
	show(a);
	a = 1'bZ;
	show(a);
end
endprogram
#include <stdio.h>
#include "svdpi.h"

void  displaylogicvec(svLogicVecVal *l) {
       printf (" data = %d control = %d \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", l->aval, l->bval) ; 
}

void  displaybitvec(const svBitVecVal *k) { 
       printf (" data = %d\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n " , k) ; 
}
module top;
import "DPI-C" function void displaylogicvec(logic [7:0] i);
import "DPI-C" function void displaybitvec(bit [7:0] i);

bit [7:0] k ;
logic [7:0] l ;

initial begin
        k = 25 ;
        l = 40 ;
        displaylogicvec(l) ;
        l = 4’hx;
        displaylogicvec(l) ;
        l = 8’hz;
        displaylogicvec(l) ;
        displaybitvec(k) ;
        $display("The End.");
end
endmodule

在DPI中使用数组

使用压缩数组(Packed Arrays)

压缩数组表示为一个或多个元素的数组,每个元素表示一组32位数据

#include "svdpi.h"

void get_nums (svLogicVecVal nums[10]) {
int i;
for (i=0; i<10; i++) {
	nums[i] = i ;
}
}
program main; 

import "DPI-C" function void get_nums(output logic [15:0] nums[10]); 

logic [15:0] nums[10]; 

initial begin 
	get_nums(nums); 
	foreach (nums[i]) 
		$display(i,nums[i]); 
end 
endprogram 
使用开放数组(Open arrays)

压缩数组维度,非压缩维度或两个维度的大小可以保持未指定,这种情况称为开放数组(或未定义大小的数组)
先看个例子:

#include <stdio.h> 
#include <svdpi.h> 

void pass_array(const svOpenArrayHandle dyn_arr ) { 
int i; 

printf("Array Left %d, Array Right %d \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", svLeft(dyn_arr,1), svRight(dyn_arr, 1) ); 
for (i= svRight(dyn_arr,1); i <= svLeft(dyn_arr,1); i++) { 
	printf("C: %d %d \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", i, *(int*)svGetArrElemPtr1(dyn_arr, i) ); 
} 
printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n"); 
} 
program main; 
int fxd_arr_1[8:3]; 
int fxd_arr_2[12:1]; 
import "DPI-C" context function void pass_array(input int dyn_arr[] ); 

initial begin 
	for (int i = 3; i<=8 ; i++) begin 
		fxd_arr_1[i] = $random(); 
		$display("SV:fxd_arr_1 %0d %d ",i, fxd_arr_1[i] ); 
	end 
	pass_array( fxd_arr_1 ); 

	for (int i = 1; i<=12 ; i++) begin 
		fxd_arr_2[i] = $random() ; 
		$display("SV: fxd_arr_2 %0d %d ",i, fxd_arr_2[i] ); 
	end 
	pass_array( fxd_arr_2 ); 
end 
endprogram
开放数组提供了一系列查询和访问数组的方法
functionDescription
int svLeft(const svOpenArrayHandle h, int d);Left bound for dimension d
int svRight(h, d)Right bound for dimension d
int svLow(h, d)Low bound for dimension d
int svHigh(h, d)High bound for dimension d
int svIncrement(h, d)If left >= right 1 else -1
int svSize(h, d)Number of elements in dimension d: svHigh−svLow+1
int svDimensions(h)Number of dimensions in open array
int svSizeOfArray(h)Total size of array in bytes
void *svGetArrayPtr(const svOpenArrayHandle h)storage for the entire array
void svGetArrElemPtr(const svOpenArrayHandle h, int i1, …)an element in the array
void *svGetArrElemPtr1(h, i1)an element in a 1-D array
void *svGetArrElemPtr2(h, i1, i2)an element in a 2-D array
void *svGetArrElemPtr3(h, i1, i2, i3)an element in a 3-D array

开放数组查询方法实例:

#include <stdio.h> 
#include <svdpi.h> 

void pass_array(const svOpenArrayHandle dyn_arr ) { 
	printf("Array Pointer is %x \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", svGetArrayPtr(dyn_arr) ); 
	printf(" Lower index %d \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", svLow(dyn_arr,1)); 
	printf(" Higher index %d \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", svHigh(dyn_arr, 1) ); 
	printf(" Left index %d \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", svLeft(dyn_arr,1)); 
	printf(" Right index %d \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", svRight(dyn_arr, 1) ); 
	printf(" Length of array %d \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", svLength(dyn_arr,1) ); 
	printf(" Incremental %d \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n",svIncrement(dyn_arr,1)); 
	printf("Dimentions of Array %d \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", svDimensions(dyn_arr )); 
	printf("Size of Array in bytes %d \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", svSizeOfArray(dyn_arr) ); 
}
program main; 

int fxd_arr_1[8:3]; 
int fxd_arr_2[1:13]; 

import "DPI-C" context function void pass_array(input int dyn_arr[] ); 

initial 
begin 
$display("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n Passing fxd_arr_1 to C \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n"); 
pass_array( fxd_arr_1 ); 
$display("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n Passing fxd_arr_2 to C \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n"); 
pass_array( fxd_arr_2 ); 
end 

endprogram 

打印信息如下:

Passing fxd_arr_1 to C

Array Pointer is 80fdc58
Lower index 3
Higher index 8
Left index 8
Right index 3
Length of array 6
Incremental 1
Dimentions of Array 1
Size of Array in bytes 24

Passing fxd_arr_2 to C

Array Pointer is 80fdc70
Lower index 1
Higher index 13
Left index 1
Right index 13
Length of array 13
Incremental -1
Dimentions of Array 1
Size of Array in bytes 52

在DPI中使用结构体

  • 在传递“struct”数据类型时,数据被打包到数组中并从SV传递到C,然后数组被解码回到C中的“struct”中
#include "stdio.h" 
#include "svdpi.h" 
extern "C" { 
typedef struct{ 
int a; 
int b; 
char c; 
} C_struct; 

extern void export_func(svBitVecVal x[3] ); 
void import_func() { 
C_struct s_data; 
unsigned int arr[3]; 

s_data.a = 51; 
s_data.b = 242; 
s_data.c = 35; 

printf( "C : s_data.a = %d\\\\\\\\\\\\\\\\n", s_data.a ); 
printf( "C : s_data.b = %d\\\\\\\\\\\\\\\\n", s_data.b ); 
printf( "C : s_data.c = %d\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\n", s_data.c ); 

arr[0] = s_data.a ; 
arr[1] = s_data.b ; 
arr[2] = s_data.c ; 
export_func(arr); 
}
program main; 

export "DPI-C" function export_func; 
import "DPI-C" function void import_func(); 

typedef struct packed{ 
int a; 
int b; 
byte c; 
} SV_struct; 

function void export_func(input int arr[3]); 
SV_struct s_data; 

s_data.a = arr[0]; 
s_data.b = arr[1]; 
s_data.c = arr[2]; 

$display("SV: s_data.a = %0d", s_data.a ); 
$display("SV: s_data.b = %0d", s_data.b ); 
$display("SV: s_data.c = %0d \\\\\\\\\\\\\\\\n", s_data.c ); 
endfunction 

initial begin 
import_func(); 
end 

endprogram
  • 在SV和C/C++代码使用定义的未压缩的结构体数据类型
#include "stdio.h"
#include "svdpi.h"

extern "C" {

	typedef struct {
		int a;
		int b;
	}  mystruct;

	void mydisplay(mystruct *s1) {
		int s2;
		printf("C: gets values from SV, s1.a=%d, s1.b=%d\\\\\\\\\\\\\\\\n",s1->a,s1->b);
		s1->a = 100;
		s1->b = 200;
		printf("C: set values,  s1.a=%d, s1.b=%d\\\\\\\\\\\\\\\\n",s1->a,s1->b);
	}
}
program p1;
	typedef struct {
		int a;
		int b;
	} mystruct;

	import "DPI-C" function void mydisplay(inout mystruct s1);
	mystruct s1;
	initial begin
		s1.a =10;
		s1.b =20;
		$display("SV: s1.a=%0d,s1.b=%0d",s1.a,s1.b);

		mydisplay(s1);
		$display("SV after DPI call: s1.a=%0d,s1.b=%0d",s1.a,s1.b);
	end 
	
endprogram

试着将上面例子中sv端结构体,改为packed类型,试试看C端打印信息会是什么样的?

  • 压缩的结构体是包含packed保留字的结构体。 在结构内,保证了位连续性。 因此,成员也必须是矢量类型。 (不要混合real / shortreal。)如果混合使用2值或者4值逻辑,它们将在内存布局方面生成4个值,因此不要混用它们。
#include "svdpi.h"
extern void func(svBitVecVal*);

int struct_operation()
{

   svBitVecVal rgb;
   svPutPartselBit(&rgb,1,0,8);//b
   svPutPartselBit(&rgb,2,8,8);//g
   svPutPartselBit(&rgb,3,16,8);//r
 
   func(&rgb);
 
   svBitVecVal blue=0;
   svBitVecVal red=0;
   svBitVecVal green=0;
 
   svGetPartselBit(&blue,&rgb,0,8);
   svGetPartselBit(&green,&rgb,8,8);
   svGetPartselBit(&red,&rgb,16,8);
 
   io_printf("C: data from SV side. red %3d green %3d blue %3d.\\\\\\\\\\\\\\\\n",red,green,blue);
 
   return 0;
}
module root_scope;
       
    export "DPI-C" function func;
    import "DPI-C" context task struct_operation();
 
   typedef struct packed {
      byte red;//MSB
      byte green;
      byte blue;//LSB ↑
   } RGB_TYPE;
 
   function void func(inout RGB_TYPE A);
      $display("SV: data from C side. red=%3d blue=%3d green=%3d.",A.red,A.green,A.blue);
      A.blue=101;
      A.green=102;
      A.red=103;
      $display("SV: data change for C side read.");
          
   endfunction
 
   initial begin
      struct_operation();
   end
 
endmodule
  • 4
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
共31个 01.拼好骑订封面-选择前面二页删除其它页.eal 02.拼好骑订内文-删除前面二页.eal 03.单P未拼-封面-选择除了前面两页和最后两页之外的所有页面-删除.eal 04.单P未拼-内文-删除前面两页和最后两页.eal 05.所有页面-改为横向.eal 05.所有页面-改为纵向.eal 06.删除单黑页面.eal 07.删除彩色页面.eal 08.删除第1P.eal 08.删除第1P和最后1P.eal 08.封面-选择除了第1p和最后1之外的所有页面-删除.eal 09.删除除第一页之外的所有页面.eal 10.删除不同位置-多页面.eal 11.删除2-237.eal 12.双面-丛向转横向.eal 13.将页面内容可视部分居中.eal 14.将页面内容居中.eal 15.将页面转换为图像@ 300dpi - JPEG高.eal 15.将页面转换为图像@ 400dpi - JPEG高-RGB.eal 15.将页面转换为图像(删除白线)@ 1200dpi.eal 16.2.提取页面.eal 16.提取页面.eal 17.检查页面大小是否相同.eal 18.移动页面内容向上1mm.eal 18.移动页面内容向下1mm.eal 18.移动页面内容向右1mm.eal 18.移动页面内容向右3mm.eal 19.移动页面内容向右移8mm.eal 20.移动页面内容向上3mm.eal 20.移动页面内容向左1mm.eal 20.移动页面内容向左3mm.eal 21.移动页面内容向左移8mm.eal 22.选择70x85页面删除其它页面.eal 23.选择140x85页面删除其它页面.eal 24.选择210x85页面删除其它页面.eal 25.调整页面顺序.eal 26.首页放到第2页后面.eal 26.首页放到第3页后面.eal 27.尾页前插入2个空白页.eal 27.尾页前插入空白页.eal 27.尾页后插入2个空白页.eal 27.尾页后插入3个空白页.eal 27.尾页后插入空白页.eal 28.--------------------------所有页后插入空白页.eal 28.第2页前和尾页后插入空白页.eal 28.首页前和尾页后插入空白页.eal 28.首页前插入空白页.eal 28.首页后和尾页前插入空白页.eal 28.首页后插入空白页.eal 29.倒数第2页放到首页.eal 29.第2页放到尾页.eal 30.尾页放到首页.eal 30.首页放到尾页.eal 31.将作品框定义为裁切框.eal
全书pdf 210M, 共分9个分卷, 这是第2分卷 中文名: 精通CSS与HTML设计模式 英文名: Pro CSS and HTML Design Patterns 资源格式: PDF 版本: 中文版高清扫描版&英文版 发行时间: 2008年9月 地区: 大陆,美国 语言: 简体中文,英文 简介: 本书是一部常实用的CSS 与HTML(XHTML)解决方案手册。书中包含了350 多种可以立即使用的设计模式(涉及文本、背景、边框、图片、表格、布局等多方面),并介绍了每种模式的原理和使用。每种设计模式、示例和源代码都经过了精心设计,易于实现和使用。通过阅读此书,可大大提高读者在Web 设计和开发中的效率和创造力。 本书结构清晰,示例丰富,实践性强,适用于所有Web 开发和设计人员。 编辑推荐 Amazon盛誉图书,业界专家十余年功力结晶,参透CSS与HTML,350多种可以立刻用于实战的设计模式,Web设计与开发人员的必备参考书。 “不管你是什么水平的开发人员,本书都是必备的参考书。”          ——Jonathan Snook。著名web程序员,The Art andScience of CSS一书作者  “我太喜欢这本书了。事实上我买了两本。一本放在公司,一本放在家里……本书讲解常系统,既值得通读,也是绝佳的参考书……赶紧买一本好好研读吧。”             ——JavaRarlch.com 由于浏览器不兼容、缺乏开发环境支持等因素。Web开发至今仍然是一项难言轻松的工作。事实上,为了简化Web开发,全球广大程序员已经开发了各种技术、众多框架和库,甚至出现五花八门的旁门左道。但是。“银弹”并没有出现。 本书中。Web开发专家MlchaeI Bowers通过350多种设计模式总结了自己多年的Web开发经验,并详细讲解了每种模式的工作原理。每种设计模式、示例和源代码都经过了精心设计,可以很方便地在实际项目中使用。本书既是一部优秀的教程。可以系统而深入地学习CSS和HTML;也是不可或缺的参考书,可以大大提高你在Web设计和开发中的效率和创造力。 作者简介 Michael Bowers,资深Web开发专家,有18年专业软件开发经验。曾经作为首席软件工程师和架构师开发过各种项目,包括许多网站、应用程序框架、编译器、自定义语言,自动化工厂和销售管理系统。他拥有音乐理论硕士学位,是一名优秀的钢琴家。 图书信息: 书名:精通CSS与HTML设计模式 (Pro CSS and HTML Design Patterns) 作者:[美]Michael Bowers 著,刘申 朱瑜敏 鲁奇 译 出版社:人民邮电出版社 出版日期:2008年9月 ISBN:978-7-115-18553-2 页数:479页 定价:¥69.00 扫描:400DPI,黑白 这本书因为是奇偶页左右对照看的,所以直接扫描双页,没有拆分。 目录: 第1章 设计模式:轻松搞定CSS! 第2章 HTML设计模式 第3章 CSS选择符与继承 第4章 盒模型 第5章 盒模型的尺寸 第6章 盒模型的属性 第7章 定位模型 第8章 定位:缩进、偏移与对齐 第9章 定位:进阶 第10章 为文本赋予样式 第11章 分割内容 第12章 对齐内容 第13章 块状元素 第14章 图片 第15章 表格 第16章 列布局 第17章 布局 第18章 字母下沉 第19章 强调框和引用 第20章 提示框 索引....

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值