前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >压缩算法:基于FPGA的Varint编码实现(附代码)

压缩算法:基于FPGA的Varint编码实现(附代码)

原创
作者头像
FPGA技术江湖
修改于 2021-04-02 10:06:18
修改于 2021-04-02 10:06:18
82800
代码可运行
举报
文章被收录于专栏:FPGA技术江湖FPGA技术江湖
运行总次数:0
代码可运行

压缩算法:基于FPGA的Varint编码实现(附代码)

今天是画师第二次和各位大侠见面,执笔绘画FPGA江湖,本人最近项目经验,写了篇基于FPGA的Varint编码(压缩算法)实现,这里分享给大家,仅供参考。如有转载,请在文章底部留言,请勿随意转载,否则有责必究。

一、概念

什么是Varint编码呢?首先我们来介绍一下Varint编码,Varint编码就是一种用一个或多个字节将数据序列化,并对数据进行压缩的方法,因此也可以称之为Varint压缩算法。

在进行数据传输过程,我们经常用大位宽来进行数据的传输。有时候是32位或者64位传输某个数据,然而,一直使用大位宽来传输数据也有它的缺点,比如传输很小的数据时,会造成资源的浪费。

例如,我们要传送一个1,而用64位来传输的话就需要表示为00000000_00000000_00000000_00000000_00000000_000000000_00000000_00000001,用这样的方式来传输一个1需要消耗8Byte的存储,属实是很浪费存储空间,而使用Varint编码对它进行压缩后,我们只需要一个Byte就能将它传输出去,大大节省了存储空间,避免了资源的浪费。

二、设计原理

下面我们就来介绍一下Varint编码是如何对原有数据进行编码处理的。在介绍Varint编码原理之前,我们先介绍一下字节数据的两种排序方式,大端和小端。大端数据指的是将高位的数据存在低位的地址中,例如将0x01234567存入一个64位的寄存器reg,则存入高位reg[7]的是7,然后依次是reg[6]=6、reg[5]=5、reg[4]=4、reg[3]=3、reg[2]=2、reg[1]=1、reg[0]=0,即逆序存入寄存器中,这种方式就称之为大端序。小端序即反之,高位的数据存入高地址,低位的数据放入低地址。

在这基础上我们再来讲Varint编码的原理,Varint编码使用的就是大端序。Varint编码将有无效数据去除,然后将效数据分成若干个组,每个组为8位,即一个字节,除去最后一个字节外,其余有效组最高位均为1,最后一个字节最高位为0。有效组最高位为1即代表这个字节后面还有有效数据组,当有效数据组最高位为0时则代表当前有效组为最后一个有效字节,除去最高位,其余位均为有效数据。

我们可以举个例子来更加详细的说明这个原理。 仍然以64位数据为例,如00000000_00000000_00010001_11011001_00110011_10101001_11001100_00110011。编码步骤如下:

(1)首先从最后一个字节开始进行编码,最后一个字节为00110011,按照编码规则我们取后七位,即截取0110011,因为后面还有数据,则最高位取1,然后与截取的有效数据组合在一起组成第一个有效数据组10110011,然后放在整个数据的最高位。

(2)然后是第二个数据,同样往前取七位,得到0011000,同样在本组最高位补1,即得到10011000,组合第一个数据组则为10110011_10011000。

(3)第三个数据,再往前取七位,得到0100111,在本有效数据组最高位补1,得到10100111,再拼接到前面的有效数据组之后,即10110011_10011000_10100111。

(4)第四个数据,同样的方式往前取七位,得到0011101,最高位补1,得到10011101,继续拼接在有效数据组后面,即10110011_10011000_10100111_10011101。

(5)第五个数据,再往前取七位,得到0010011,在最高位补1,得到10010011,继续往有效数据组后拼接,得到10110011_10011000_10100111_10011101_10010011。

(6)第六个数据,按照上述方法,可得10111011,拼接后可得10110011_10011000_10100111_10011101_10010011_10111011。

(7)第七个数据,取得0000100,由观察得知,这个有效数据组之后均为0,即有效数据已全部截取完毕,则按照Varint编码规则,最高位补0,完成编码,将数据全部拼接后得到进行Varint编码后的数据,即10110011_10011000_10100111_10011101_10010011_10111011_00000100。

将上述进行Varint编码后得到的有效数据组与原数据相比,节省了一个字节的存储资源。解码只要将上述过程逆序进行即可,这里就不过多赘述。熟悉完了Varint编码的原理,下面我们就可以开始进行设计了。

三、架构设计

设计架构如下图:

将本设计模块命名为varint_encode,clk为输入时钟,rst_n为复位信号,idata为64位是输入数据,ivalid为数据有效信号,odata0~odata7为输出的有效数据,ovalid0~ovalid7为伴随输出有效数据的数据有效信号。由于FPGA输出的数据位宽都是固定的,因此需要将各个压缩后的位宽都定义一遍。

四、Verilog 代码实现

功能模块实现代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module varint_encode(

  input      wire                        clk,
  input      wire                        rst_n,
  
  input      wire            [63:0]      idata,
  input      wire                        ivalid,
  
  output     reg             [63:0]      odata0,
  output     reg             [55:0]      odata1,
  output     reg             [47:0]      odata2,
  output     reg             [39:0]      odata3,
  output     reg             [31:0]      odata4,
  output     reg             [23:0]      odata5,
  output     reg             [15:0]      odata6,
  output     reg             [7:0]       odata7,
  
  output     reg                         ovalid0,
  output     reg                         ovalid1,
  output     reg                         ovalid2,
  output     reg                         ovalid3,
  output     reg                         ovalid4,
  output     reg                         ovalid5,
  output     reg                         ovalid6,
  output     reg                         ovalid7
);
  
  reg                        [63:0]      idata_r;
  reg                        [7:0]       buff0;
  reg                        [7:0]       buff1;
  reg                        [7:0]       buff2;
  reg                        [7:0]       buff3;
  reg                        [7:0]       buff4;
  reg                        [7:0]       buff5;
  reg                        [7:0]       buff6;
  reg                        [7:0]       buff7;
  reg                        [7:0]       buff8;
  reg                        [7:0]       buff9;
  
  reg                                    buff0_req;
  reg                                    buff1_req;
  reg                                    buff2_req;
  reg                                    buff3_req;
  reg                                    buff4_req;
  reg                                    buff5_req;
  reg                                    buff6_req;
  reg                                    buff7_req;
  reg                                    buff8_req;
  reg                                    buff9_req;

  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0)
    idata_r <= 64'd0;
  else
    if (ivalid == 1'b1)
      idata_r <= idata;
    else
      idata_r <= idata_r;
  end
  
  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0) begin
    buff0 <= 8'd0;
    buff0_req <= 1'b0;
  end
  else
    if (idata_r[6:0] > 0) begin
      buff0 <= {1'b1,idata_r[6:0]};
    buff0_req <= 1'b1;
      end
    else begin
      buff0 <= 8'd0;
    buff0_req <= 1'b0;
    end
  end
  
  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0) begin
    buff1 <= 8'd0;
    buff1_req <= 1'b0;
  end
  else
    if (idata_r[13:7] > 0) begin
      buff1 <= {1'b1,idata_r[13:7]};
    buff1_req <= 1'b1;
    end
    else begin
      buff1 <= 8'd0;
    buff1_req <= 1'b0;
    end
  end
  
  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0) begin
    buff2 <= 8'd0;
    buff2_req <= 1'b0;
  end
  else
    if (idata_r[20:14] > 0) begin
      buff2 <= {1'b1,idata_r[20:14]};
    buff2_req <= 1'b1;
      end
    else begin
      buff2 <= 8'd0;
    buff2_req <= 1'b0;
    end
  end
  
  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0) begin
    buff3 <= 8'd0;
    buff3_req <= 1'b0;
  end
  else
    if (idata_r[27:21] > 0) begin
      buff3 <= {1'b1,idata_r[27:21]};
    buff3_req <= 1'b1;
    end
    else begin
      buff3 <= 8'd0;
    buff3_req <= 1'b0;
      end
  end
  
  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0) begin
    buff4 <= 8'd0;
    buff4_req <= 1'b0;
  end
  else
    if (idata_r[34:28] > 0) begin
      buff4 <= {1'b1,idata_r[34:28]};
    buff4_req <= 1'b1;
      end
    else begin
      buff4 <= 8'd0;
    buff4_req <= 1'b0;
    end
  end
  
  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0) begin
    buff5 <= 8'd0;
    buff5_req <= 1'b0;
  end
  else
    if (idata_r[41:35] > 0) begin
      buff5 <= {1'b1,idata_r[41:35]};
    buff5_req <= 1'b1;
    end
    else begin
      buff5 <= 8'd0;
    buff5_req <= 1'b0;
    end
  end
  
  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0) begin
    buff6 <= 8'd0;
    buff6_req <= 1'b0;
  end
  else
    if (idata_r[48:42] > 0) begin
      buff6 <= {1'b1,idata_r[48:42]};
    buff6_req <= 1'b1;
    end
    else begin
      buff6 <= 8'd0;
    buff6_req <= 1'b0;
    end
  end
  
  
  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0) begin
    buff7 <= 8'd0;
    buff7_req <= 1'b0;
  end
  else
    if (idata_r[55:49] > 0) begin
      buff7 <= {1'b1,idata_r[55:49]};
    buff7_req <= 1'b1;
    end
    else begin
      buff7 <= 8'd0;
    buff7_req <= 1'b0;
    end
  end
  
  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0) begin
    buff8 <= 8'd0;
    buff8_req <= 1'b0;
  end
  else
    if (idata_r[62:56] > 0) begin
      buff8 <= {1'b1,idata_r[62:56]};
    buff8_req <= 1'b1;
    end
    else begin
      buff8 <= 8'd0;
    buff8_req <= 1'b0;
    end
  end
  
  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0) begin
    buff9 <= 8'd0;
    buff9_req <= 1'b0;
  end
  else
    if (idata_r[63] == 1'b1) begin
      buff9 <= {1'b0,5'b00000,idata_r[63]};
    buff9_req <= 1'b1;
    end
    else begin
      buff9 <= 8'd0;
    buff9_req <= 1'b0;
    end
  end
  
  always @ (posedge clk,negedge rst_n) begin
    if (rst_n == 1'b0) begin
    odata0 <= 64'd0;
    odata1 <= 56'd0;
    odata2 <= 48'd0;
    odata3 <= 40'd0;
    odata4 <= 32'd0;
    odata5 <= 24'd0;
    odata6 <= 16'd0;
    odata7 <= 8'd0;
    ovalid0 <= 1'b0;
    ovalid1 <= 1'b0;
    ovalid2 <= 1'b0;
    ovalid3 <= 1'b0;
    ovalid4 <= 1'b0;
    ovalid5 <= 1'b0;
    ovalid6 <= 1'b0;
    ovalid7 <= 1'b0;
  end
  else
    casex({buff0_req,buff1_req,buff2_req,buff3_req,buff4_req,buff5_req,buff6_req,buff7_req})
      8'b0000_0000      :  begin
                           odata0 <= 64'd0; ovalid0 <= 1'b0;
                 odata1 <= 56'd0; ovalid1 <= 1'b0;
                 odata2 <= 48'd0; ovalid1 <= 1'b0;
                 odata3 <= 40'd0; ovalid1 <= 1'b0;
                 odata4 <= 32'd0; ovalid1 <= 1'b0;
                 odata5 <= 24'd0; ovalid1 <= 1'b0;
                 odata6 <= 16'd0; ovalid1 <= 1'b0;
                 odata7 <= 8'd0; ovalid1 <= 1'b0;
               end
               
    8'b1000_0000      :  begin
                           odata0 <= 64'd0; ovalid0 <= 1'b0;
                 odata1 <= 56'd0; ovalid1 <= 1'b0;
                 odata2 <= 48'd0; ovalid1 <= 1'b0;
                 odata3 <= 40'd0; ovalid1 <= 1'b0;
                 odata4 <= 32'd0; ovalid1 <= 1'b0;
                 odata5 <= 24'd0; ovalid1 <= 1'b0;
                 odata6 <= 16'd0; ovalid1 <= 1'b0;
                 odata7 <= buff0; ovalid7 <= 1'b1;
               end
                             
    8'bx100_0000      :  begin
                           odata0 <= 64'd0; ovalid0 <= 1'b0;
                 odata1 <= 56'd0; ovalid1 <= 1'b0;
                 odata2 <= 48'd0; ovalid1 <= 1'b0;
                 odata3 <= 40'd0; ovalid1 <= 1'b0;
                 odata4 <= 32'd0; ovalid1 <= 1'b0;
                 odata5 <= 24'd0; ovalid1 <= 1'b0;
                 odata6 <= {buff0,buff1}; ovalid6 <= 1'b1;
                 odata7 <= 8'd0; ovalid7 <= 1'b0;
               end
                 
    8'bxx10_0000      :  begin
                           odata0 <= 64'd0; ovalid0 <= 1'b0;
                 odata1 <= 56'd0; ovalid1 <= 1'b0;
                 odata2 <= 48'd0; ovalid1 <= 1'b0;
                 odata3 <= 40'd0; ovalid1 <= 1'b0;
                 odata4 <= 32'd0; ovalid1 <= 1'b0;
                 odata5 <= {buff0,buff1,buff2}; ovalid5 <= 1'b1;
                 odata6 <= 16'd0; ovalid1 <= 1'b0;
                 odata7 <= 8'd0; ovalid7 <= 1'b0;
               end
                 
    8'bxxx1_0000      :  begin
                           odata0 <= 64'd0; ovalid0 <= 1'b0;
                 odata1 <= 56'd0; ovalid1 <= 1'b0;
                 odata2 <= 48'd0; ovalid1 <= 1'b0;
                 odata3 <= 40'd0; ovalid1 <= 1'b0;
                 odata4 <= {buff0,buff1,buff2,buff3}; ovalid4 <= 1'b1;
                 odata5 <= 24'd0; ovalid1 <= 1'b0;
                 odata6 <= 16'd0; ovalid1 <= 1'b0;
                 odata7 <= 8'd0; ovalid7 <= 1'b0;
               end
               
    8'bxxxx_1000      :  begin
                           odata0 <= 64'd0; ovalid0 <= 1'b0;
                 odata1 <= 56'd0; ovalid1 <= 1'b0;
                 odata2 <= 48'd0; ovalid1 <= 1'b0;
                 odata3 <= {buff0,buff1,buff2,buff3,buff4}; ovalid3 <= 1'b1;
                 odata4 <= 32'd0; ovalid1 <= 1'b0;
                 odata5 <= 24'd0; ovalid1 <= 1'b0;
                 odata6 <= 16'd0; ovalid1 <= 1'b0;
                 odata7 <= 8'd0; ovalid7 <= 1'b0;
               end
               
    8'bxxxx_x100      :  begin
                           odata0 <= 64'd0; ovalid0 <= 1'b0;
                 odata2 <= {buff0,buff1,buff2,buff3,buff4,buff5}; ovalid2 <= 1'b1;
                 odata3 <= 40'd0; ovalid1 <= 1'b0;
                 odata4 <= 32'd0; ovalid1 <= 1'b0;
                 odata5 <= 24'd0; ovalid1 <= 1'b0;
                 odata6 <= 16'd0; ovalid1 <= 1'b0;
                 odata7 <= 8'd0; ovalid1 <= 1'b0;
               end
    
    8'bxxxx_xx10      :  begin
                           odata0 <= 64'd0; ovalid0 <= 1'b0;
                 odata1 <= {buff0,buff1,buff2,buff3,buff4,buff5,buff6}; ovalid1 <= 1'b1;
                 odata2 <= 48'd0; ovalid1 <= 1'b0;
                 odata3 <= 40'd0; ovalid1 <= 1'b0;
                 odata4 <= 32'd0; ovalid1 <= 1'b0;
                 odata5 <= 24'd0; ovalid1 <= 1'b0;
                 odata6 <= 16'd0; ovalid1 <= 1'b0;
                 odata7 <= 8'd0; ovalid1 <= 1'b0;
               end 
    
    8'bxxxx_xxx1      : begin
                             odata0 <= {buff0,buff1,buff2,buff3,buff4,buff5,buff6,buff7}; ovalid0 <= 1'b1;
                 odata1 <= 56'd0; ovalid1 <= 1'b0;
                 odata2 <= 48'd0; ovalid1 <= 1'b0;
                 odata3 <= 40'd0; ovalid1 <= 1'b0;
                 odata4 <= 32'd0; ovalid1 <= 1'b0;
                 odata5 <= 24'd0; ovalid1 <= 1'b0;
                 odata6 <= 16'd0; ovalid1 <= 1'b0;
                 odata7 <= 8'd0; ovalid1 <= 1'b0;
               end
               
    default           :  begin
                             odata0 <= {buff0,buff1,buff2,buff3,buff4,buff5,buff6,buff7}; ovalid0 <= 1'b1;
                 odata1 <= 56'd0; ovalid1 <= 1'b0;
                 odata2 <= 48'd0; ovalid1 <= 1'b0;
                 odata3 <= 40'd0; ovalid1 <= 1'b0;
                 odata4 <= 32'd0; ovalid1 <= 1'b0;
                 odata5 <= 24'd0; ovalid1 <= 1'b0;
                 odata6 <= 16'd0; ovalid1 <= 1'b0;
                 odata7 <= 8'd0; ovalid1 <= 1'b0;
               end   
    endcase
  end

endmodule 

五、仿真测试及结果

仿真测试代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
`timescale 1ns/1ps

module varint_encode_tb;

  reg                     clk;
  reg                     rst_n;
  reg                     ivalid;
  reg          [63:0]     idata;
  
  wire         [63:0]     odata0;
  wire         [55:0]     odata1;
  wire         [47:0]     odata2;
  wire         [39:0]     odata3;
  wire         [31:0]     odata4;
  wire         [23:0]     odata5;
  wire         [15:0]     odata6;
  wire         [7:0]      odata7;
  
  wire                    ovalid0;
  wire                    ovalid1;
  wire                    ovalid2;
  wire                    ovalid3;
  wire                    ovalid4;
  wire                    ovalid5;
  wire                    ovalid6;
  wire                    ovalid7;

  varint_encode varint_encode_inst(

    .clk                    (clk),
    .rst_n                  (rst_n),
    
    .idata                  (idata),
    .ivalid                 (ivalid),
    
    .odata0                 (odata0),
    .odata1                 (odata1),
    .odata2                 (odata2),
    .odata3                 (odata3),
    .odata4                 (odata4),
    .odata5                 (odata5),
    .odata6                 (odata6),
    .odata7                 (odata7),
    
    .ovalid0                (ovalid0),
    .ovalid1                (ovalid1),
    .ovalid2                (ovalid2),
    .ovalid3                (ovalid3),
    .ovalid4                (ovalid4),
    .ovalid5                (ovalid5),
    .ovalid6                (ovalid6),
    .ovalid7                (ovalid7)
  );

  initial clk = 1'b0;
  always # 10 clk = ~clk;
  
  initial begin
    rst_n = 1'b0;
  ivalid = 1'b0;
  idata = 64'd0;
  # 201;
  rst_n = 1'b1;
  # 200;
  

  @ (posedge clk);
  # 2;
  idata = 64'b00000000_00000000_00010001_11011001_00110011_10101001_11001100_00110011;
  ivalid = 1'b1;
  @ (posedge clk);
  # 2;
  idata = 64'd0;
  ivalid = 1'b0;
  
  @ (posedge clk);
  # 2;
  idata = 64'b00000000_00000001_00010001_11011001_00110011_10101001_11001100_00110011;
  ivalid = 1'b1;
  @ (posedge clk);
  # 2;
  idata = 64'd0;
  ivalid = 1'b0;
  
  @ (posedge clk);
  # 2;
  idata = 64'b00000000_00000000_00000001_11011001_00110011_10101001_11001100_00110011;
  ivalid = 1'b1;
  @ (posedge clk);
  # 2;
  idata = 64'd0;
  ivalid = 1'b0;
  
  @ (posedge clk);
  # 2;
  idata = 64'b00000000_00000000_00000000_00000001_00110011_10101001_11001100_00110011;
  ivalid = 1'b1;
  @ (posedge clk);
  # 2;
  idata = 64'd0;
  ivalid = 1'b0;
  
  @ (posedge clk);
  # 2;
  idata = 64'b00000000_00000000_00000000_00000000_00000000_10101001_11001100_00110011;
  ivalid = 1'b1;
  @ (posedge clk);
  # 2;
  idata = 64'd0;
  ivalid = 1'b0;
  
  
  # 2000;
  $stop;
  end

endmodule 

仿真结果:

将得到的仿真结果与上文经过Varint编码压缩后的结果对比可知,仿真结果正确。

五、总结

在进行原理理解与设计实现的时候,需要注意,逆序是字节的逆序,并非每一bit的数据都要进行逆序,且最高位是补位,代表后面还有无数据,并非是实际数据,在进行解码的时候要注意去掉每一个有效数据组的最高位,再进行拼接,这样得到的数据才是正确的数据,否则得到的将是错误数据。考虑到FPGA位宽定义的局限性,需要对每一个可能性的位宽大小均进行定义,并且定义一个相应的脉冲信号,告诉后级模块哪一个数据是有效的,这样设计才不会出错,否则输出的大小与原来输入的大小相同,也就失去了设计的意义。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
FPGA零基础学习:SDR SDRAM 驱动设计
本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
FPGA技术江湖
2021/03/23
1K0
FPGA零基础学习:SDR SDRAM 驱动设计
sdram控制器设计
同步动态随机存取内存(synchronous dynamic random-access memory,简称SDRAM)是有一个同步接口的动态随机存取内存(DRAM)。SDRAM的特点是需要定期进行刷新操作,这也要求SDRAM需要一个控制器来对SDRAM进行控制,更为详细的SDRAM的知识可以上网进行查找,这里不再做过多的阐述。
全栈程序员站长
2022/09/07
6300
sdram控制器设计
FPGA零基础学习:IIC协议驱动设计
本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
FPGA技术江湖
2021/03/23
1.3K0
FPGA零基础学习:IIC协议驱动设计
FPGA 的数字信号处理:Verilog 实现简单的 FIR 滤波器
不起眼的 FIR 滤波器是 FPGA 数字信号处理中最基本的模块之一,因此了解如何将具有给定抽头数及其相应系数值的基本模块组合在一起非常重要。因此,在这个关于 FPGA 上 DSP 基础实用入门的教程中,将从一个简单的 15 抽头低通滤波器 FIR 开始,在 Matlab 中为其生成初始系数值,然后转换这些值用于编写 Verilog 模块。
碎碎思
2023/08/30
2.1K0
FPGA 的数字信号处理:Verilog 实现简单的 FIR 滤波器
cordic的FPGA实现(三)、sin、cos函数运算与源码分析
在旋转模式中曾提到:由于每次伪旋转都导致向量模长发生了变化,以Ki表示第i次伪旋转模长补偿因子,所以第i次伪旋转真实旋转的结果应该为:
根究FPGA
2020/06/30
2.1K0
cordic的FPGA实现(三)、sin、cos函数运算与源码分析
FPGA项目开发:基于FPGA的伪随机数发生器(附代码)
今天是画师和各位大侠见面了,执笔绘画FPGA江湖,本人写了篇关于FPGA的伪随机数发生器学习笔记,这里分享给大家,仅供参考。
FPGA技术江湖
2021/04/16
1.1K0
FPGA项目开发:基于FPGA的伪随机数发生器(附代码)
FPGA零基础学习:SPI 协议驱动设计(上)
本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
FPGA技术江湖
2021/03/23
1K0
FPGA零基础学习:SPI 协议驱动设计(上)
cordic的FPGA实现(三)、乘法器实现
当CORDIC运算在齐次线性坐标系下时,可使用CORDIC实现乘法运算,这只乘法器有一些弊端,就是输入z只能是介于-2~2之间。
根究FPGA
2020/06/30
7300
cordic的FPGA实现(三)、乘法器实现
【FPGA实验】数码管动态显示
静态显示: 每一个管脚都用固定的一个电平去控制。 优点:能够做到”同时” 缺点:管脚太多
zstar
2022/06/14
7530
【FPGA实验】数码管动态显示
FPGA零基础学习:SPI 协议驱动设计
本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
FPGA技术江湖
2020/12/30
1.6K0
FPGA综合项目——SDRAM控制器
再者就是通信处理模块,具体的通信设置,发送什么命令是写?什么命令是读?发的什么数据?等等。
全栈程序员站长
2022/09/16
6470
FPGA综合项目——SDRAM控制器
求余算法的FPGA实现
遇到了一个输入的除数和被除数位宽(64~256)都很大,组合逻辑导致时序不满足要求的问题,根据恢复余数法想出这样一个解决方式:
根究FPGA
2020/06/30
1.1K0
求余算法的FPGA实现
FPGA零基础学习之Vivado-UART驱动教程
本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
FPGA技术江湖
2023/07/19
6500
FPGA零基础学习之Vivado-UART驱动教程
基于FPGA的SDRAM控制器设计(4)[通俗易懂]
前面的三篇文章,我们已经简述了基本的SDRAM的基本操作。这里总结一下SDRAM的几个模块,SDRAM的上电初始化,自刷新、读写模块、顶层仲裁控制。了解了上面的操作,我们已经可以完成SDRAM控制器的代码完成,接下来我们便完善SDRAM控制器的接口,简化该SDRAM控制器设计,使得该SDRAM控制器可以很容易的使用。下面的接口定义如下:
全栈程序员站长
2022/07/28
6910
基于FPGA的SDRAM控制器设计(4)[通俗易懂]
FPGA零基础学习:SPI 协议驱动设计(下)
该模块负责将外部写fifo中的数据写入到flash中。wr_fifo_rd为写fifo的读使能信号,wrdata为从写fifo中读出的数据,wr_len为需要写入flash中数据的长度,wr_addr为写入地址。
FPGA技术江湖
2021/03/23
1.4K0
FPGA零基础学习:SPI 协议驱动设计(下)
【收藏】FPGA数字IC刷题58个Verilog代码及讲解(状态机、跨时钟、同步/异步FIFO、DMUX、奇数/小数分频)
牛客 Verilog 刷题入门篇1~24 + 进阶篇1~34 题解代码,所有代码均能通过测试,配合视频讲解效果更佳。本文给出代码,部分题目给出必要说明。 很多题目本身出题有些问题,着重理解题目,没必要钻牛角尖。
FPGA探索者
2022/11/01
3K0
【收藏】FPGA数字IC刷题58个Verilog代码及讲解(状态机、跨时钟、同步/异步FIFO、DMUX、奇数/小数分频)
基于FPGA的ASCII码日期转时间戳算法实现
时间戳是使用数字签名技术产生的数据,签名的对象包括了原始文件信息、签名参数、签名时间等信息。时间戳系统用来产生和管理时间戳,对签名对象进行数字签名产生时间戳,以证明原始文件在签名时间之前已经存在。
FPGA技术江湖
2021/04/14
3K0
基于FPGA的ASCII码日期转时间戳算法实现
PGA零基础学习:FPGA在FPGA中何时用组合逻辑或时序逻辑
本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
FPGA技术江湖
2021/03/15
6580
PGA零基础学习:FPGA在FPGA中何时用组合逻辑或时序逻辑
CRC校验的FPGA实现
CRC定义 CRC(Cyclic Redundancy Check),循环冗余校验,其特征是信息字段和校验字段的长度可以任意选定,CRC编码格式是在k位有效数据之后添加r位校验码,形成总长度为n(K+R)位的CRC码。
根究FPGA
2020/06/30
3.6K0
CRC校验的FPGA实现
FPGA系统性学习笔记连载_Day17【打卡计数、数码管显示实验】
本系列为FPGA系统性学习学员学习笔记整理分享,如有学习或者购买开发板意向,可加交流群联系群主。
FPGA技术江湖
2021/04/07
2890
FPGA系统性学习笔记连载_Day17【打卡计数、数码管显示实验】
推荐阅读
相关推荐
FPGA零基础学习:SDR SDRAM 驱动设计
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验