Complex Multiplier IP核的使用,尤其是输出数据的截位到底怎么弄,我感觉官方文档PG104写的不清楚。我个人在网上也没找到好的讲解文章,就自己琢磨了下,然后写成文档记录在此,方便将来也有疑问的同学。
目录
1、当IP输出位宽为默认的最大值25时,此时IP没有截位。如仿真例子中第一种方法:
2、当IP输出位宽设置为20时,此时IP相对于最大值25就截掉了5位。如仿真例子中第二种方法:
3、如上第2点使用同一个IP设置:IP输出位宽设置为20时,此时IP相对于最大值25就截掉了5位。但修改输入数据的使用方法,如仿真例子中第三种方法:
4、modelsim仿真结果如下所示,可以看到仿真结果是正确的。
/*-------------------------------------------------------------------------------------------------------------------
Author: Zheng Wei
Date: 2022-10-10
Version: 1.0
Description: It is a tb_cmpy test.
-------------------------------------------------------------------------------------------------------------------*/
`timescale 1ns / 1ps
module tb_cmpy;
reg i_sys_clk ;
reg i_sys_rst ;
reg din_ena ;
reg [9 :0] din_re0 ;
reg [9 :0] din_im0 ;
reg [9 :0] din_re1 ;
reg [9 :0] din_im1 ;
// clock generate module
parameter period = 10; // 100MHz
initial begin
i_sys_clk = 1'b0;
forever #(period/2) i_sys_clk = ~i_sys_clk;
end
//-------------------------------------------------------------------
// system initialization
task task_sysinit;
begin
end
endtask
// system reset
task task_reset;
begin
i_sys_rst = 1'b1;
repeat(2) @(negedge i_sys_clk);
i_sys_rst = 1'b0;
end
endtask
initial begin
task_sysinit;
task_reset ;
repeat(10) @(posedge i_sys_clk);
// 10bit: 1 sign bit, 1 integer bit, 8 fraction bit
// case1: x0 = 0.5 + j; x1 = 1 - 0.5j
// result: x0 * x1 = 1 + 0.75j, 1 sign bit, 1 integer bit, 8 fraction bit
din_ena = 1;
din_re0 = 10'b00_1000_0000;
din_im0 = 10'b01_0000_0000;
din_re1 = 10'b01_0000_0000;
din_im1 = 10'b11_1000_0000;
@(posedge i_sys_clk);
din_ena = 0;
repeat(20) @(posedge i_sys_clk);
// 10bit: 1 sign bit, 1 integer bit, 8 fraction bit
// case2: x0 = 0.5 - j; x1 = 1 - 0.75j
// result: x0 * x1 = -0.25 - 1.375j, 1 sign bit, 1 integer bit, 8 fraction bit
din_ena = 1;
din_re0 = 10'b00_1000_0000;
din_im0 = 10'b11_0000_0000;
din_re1 = 10'b01_0000_0000;
din_im1 = 10'b11_0100_0000;
@(posedge i_sys_clk);
din_ena = 0;
repeat(500) @(posedge i_sys_clk);
$stop;
end
//------------ first method ---------------------------------------------------------------
wire fft1_ena ;
wire signed [31:0] fft1_real ;
wire signed [31:0] fft1_imag ;
wire signed [11:0] fft1_re_dout;
wire signed [11:0] fft1_im_dout;
// din: real[11:0], image[27:16]; dout: real[24:0], image[56:32].
cmpy_1 u1_cmpy(
.aclk (i_sys_clk ), // input wire aclk
.s_axis_a_tvalid (din_ena ), // input wire s_axis_a_tvalid
.s_axis_a_tdata ({4'd0,{2{din_im0[9]}},din_im0,4'd0,{2{din_re0[9]}},din_re0}), // input wire [31 : 0] s_axis_a_tdata
.s_axis_b_tvalid ( 1'b1 ), // input wire s_axis_b_tvalid
.s_axis_b_tdata ({4'd0,{2{din_im1[9]}},din_im1,4'd0,{2{din_re1[9]}},din_re1}), // input wire [31 : 0] s_axis_b_tdata
.m_axis_dout_tvalid (fft1_ena ), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata ({fft1_imag,fft1_real} ) // output wire [63 : 0] m_axis_dout_tdata
);
assign fft1_re_dout = fft1_real[8+:12]; // [19:8]: shift right 8 bit
assign fft1_im_dout = fft1_imag[8+:12]; // [19:8]: shift right 8 bit
//------------ second method ---------------------------------------------------------------
wire fft2_ena ;
wire signed [23:0] fft2_real ;
wire signed [23:0] fft2_imag ;
wire signed [11:0] fft2_re_dout;
wire signed [11:0] fft2_im_dout;
// din: real[11:0], image[27:16]; dout: real[19:0], image[43:24].
cmpy_0 u2_cmpy(
.aclk (i_sys_clk ), // input wire aclk
.s_axis_a_tvalid (din_ena ), // input wire s_axis_a_tvalid
.s_axis_a_tdata ({4'd0,{2{din_im0[9]}},din_im0,4'd0,{2{din_re0[9]}},din_re0}), // input wire [31 : 0] s_axis_a_tdata
.s_axis_b_tvalid ( 1'b1 ), // input wire s_axis_b_tvalid
.s_axis_b_tdata ({4'd0,{2{din_im1[9]}},din_im1,4'd0,{2{din_re1[9]}},din_re1}), // input wire [31 : 0] s_axis_b_tdata
.m_axis_dout_tvalid (fft2_ena ), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata ({fft2_imag,fft2_real} ) // output wire [47 : 0] m_axis_dout_tdata
);
assign fft2_re_dout = fft2_real[3+:12]; // [14:3]: shift right 8-5=3 bit
assign fft2_im_dout = fft2_imag[3+:12]; // [14:3]: shift right 8-5=3 bit
//------------ third method ---------------------------------------------------------------
wire fft3_ena ;
wire signed [23:0] fft3_real ;
wire signed [23:0] fft3_imag ;
wire signed [11:0] fft3_re_dout;
wire signed [11:0] fft3_im_dout;
// din: real[11:0], image[27:16]; dout: real[19:0], image[43:24].
cmpy_0 u3_cmpy(
.aclk (i_sys_clk ), // input wire aclk
.s_axis_a_tvalid (din_ena ), // input wire s_axis_a_tvalid
.s_axis_a_tdata ({4'd0,din_im0,2'd0,4'd0,din_re0,2'd0}), // input wire [31 : 0] s_axis_a_tdata
.s_axis_b_tvalid ( 1'b1 ), // input wire s_axis_b_tvalid
.s_axis_b_tdata ({4'd0,din_im1,2'd0,4'd0,din_re1,2'd0}), // input wire [31 : 0] s_axis_b_tdata
.m_axis_dout_tvalid (fft3_ena ), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata ({fft3_imag,fft3_real} ) // output wire [47 : 0] m_axis_dout_tdata
);
assign fft3_re_dout = fft3_real[7+:12]; // [18:7]: shift right 8+4-5=7 bit
assign fft3_im_dout = fft3_imag[7+:12]; // [18:7]: shift right 8+4-5=7 bit
endmodule


两个输入数据都是10bit宽,其中8bit为定点小数,实际上就是都左移8bit;那么相乘的结果就是左移了16bit,如果相乘的结果也是取8位为定点小数(即实际上右移8bit),那么就还需要右移8bit才能得到正确的值,也即如下代码:
assign fft1_re_dout = fft1_real[8+:12]; // [19:8]: shift right 8 bit
两个输入数据都是10bit宽,其中8bit为定点小数,实际上就是都左移8bit;那么相乘的结果就是左移了16bit,如果相乘的结果也是取8位为定点小数(即实际上右移8bit),那么就还需要右移8bit才能得到正确的值。但是因为IP已经帮我们截掉了5bit,所以此时我们只需要再截掉8-5=3bit就行了,也即如下代码:
assign fft2_re_dout = fft2_real[3+:12]; // [14:3]: shift right 8-5=3 bit
仿真中给的两个输入数据都是10bit,但IP设置的输入数据位宽是12bit,那么就需要将10bit拓宽到12bit。有两种办法:
现在来仔细讲下结尾补0的方法如何进行截位。本来两个都是10bit的数据,其中8bit为定点小数,实际上就是都左移8bit;但现在结尾补了2bit的0,那也就是总共左移了8+2=10bit了。
那么相乘的结果就是左移了20bit,如果相乘的结果也是取8位为定点小数(即实际上右移8bit),那么就还需要右移12bit才能得到正确的值。但是因为IP已经帮我们截掉了5bit,所以此时我们只需要再截掉12-5=7bit就行了,也即如下代码:
assign fft3_re_dout = fft3_real[7+:12]; // [18:7]: shift right 8+4-5=7 bit
本文完结!
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent
目前,Itembelongs_toCompany和has_manyItemVariants。我正在尝试使用嵌套的fields_for通过Item表单添加ItemVariant字段,但是使用:item_variants不显示该表单。只有当我使用单数时才会显示。我检查了我的关联,它们似乎是正确的,这可能与嵌套在公司下的项目有关,还是我遗漏了其他东西?提前致谢。注意:下面的代码片段中省略了不相关的代码。编辑:不知道这是否相关,但我正在使用CanCan进行身份验证。routes.rbresources:companiesdoresources:itemsenditem.rbclassItemi
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
如何找到调用此方法的位置?defto_xml(options={})binding.pryoptions=options.to_hifoptions&&options.respond_to?(:to_h)serializable_hash(options).to_xml(options)end 最佳答案 键入caller。这将返回当前调用堆栈。文档:Kernel#caller.例子[0]%rspecspec10/16|===================================================62=====
Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"
在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl