-
移位寄存器SRLC32E
ram_based_shifter Xilinx系列FPGA硬核IP,能够有效对移位寄存器进行处理,节省LUT资源
1,移位寄存器两种基本数据流
1、动态读操作(移位长度不固定)
(1)输出Q由5位地址决定
(2)每当一个新地址到达时,在经过访问LUT的时间延迟后,输出Q变化
(3)读操作是异步的,独立于时钟和时钟使能信号
2、静态读操作(移位长度固定)
(1)当5位地址固定时(地址固定意味着移位长度固定),输出Q使用相同的比特位
(2)该模式在一个LUT中实现了从1到32位的任何移位寄存器长度
(3)移位寄存器长度为(N + 1),其中N为输入地址(0-31)
(4)输出Q与每一次的移位操作是同步的
(5)前一位被移到下一个位置,并出现在Q输出上
2、移位寄存器例化
除了ram_based_shifter IP配置这种方式外,Xilinx FPGA使用移位寄存器资源还存在原语例化和工具推断两种方式生成shifter。
1、原语例化
// SRLC32E: 32-bit variable length cascadable shift register LUT (Mapped to a SliceM LUT6)
// with clock enable
// 7 Series
// Xilinx HDL Language Template, version 2019.1
SRLC32E #(
.INIT(32'h00000000) // Initial Value of Shift Register
) SRLC32E_inst (
.Q(Q), // SRL data output
.Q31(Q31), // SRL cascade output pin
.A(A), // 5-bit shift depth select input
.CE(CE), // Clock enable input
.CLK(CLK), // Clock input
.D(D) // SRL data input
);
// End of SRLC32E_inst instantiation
2、vivado推断
这里首先要注意的是,移位寄存器是不支持复位和置位的,所以我们的设计中要尽量避免复位和置位,防止vivado推断出现错误。
2.1采用命令
(srl_style = “ ”)
可选择的属性有:
(1)register:用FF生成SRL
(2)srl:用LUT生成SRL
(3)srl_reg:用LUT和FF生成SRL,最后一级深度用FF
(4)reg_srl:第一级深度用FF,其他用LUT
(5)reg_srl_reg:第一和最后级深度用FF,其他用LUT
(6)block:用BRAM生成SRL
也可以使用命令 ( shreg_extract = “ ”)
可选的属性有:(1)yes:使用上述的移位寄存器结构
(2)no:不使用上述移位寄存器结构
当两者同时出现时,shreg_extract的优先级更高。
//使用寄存器实现移位寄存器
(* srl_style = "register" *) reg [16:0] my_srl;
//使用SRL实现移位寄存器
(* srl_style = "srl" *) reg [16:0] my_srl;
//使用寄存器实现移位寄存器
(* shreg_extract = "no" *) reg [16:0] my_srl;
//使用SRL实现移位寄存器
(* shreg_extract = "yes" *) reg [16:0] my_srl;
Block RAM and UltraRAM Differences
BRAM与URAM是Xilinx FPGA中常见的存储器资源,BRAM可配置为18k,36k bits两种模式;URAM一般为288k bits。Block RAM 和 UltraRAM 之间的主要区别是:
- UltraRAM 具有一个单一的时钟输入,是完全同步的,并且与 Block RAM 不同,它不直接支持独立的时钟接口。
- 不支持可配置端口宽度的单个4K x 72 UltraRAM 或多个时钟域。但是,UltraRAM 块的字节写使能功能可用于在存储器结构本身之外支持此功能。
- UltraRAM 仅支持每个端口每个周期的读取或写入。
- 简单双端口(SDP) 和真正的双端口(TDP) Block RAM 模式不直接适用于UltraRAM。 UltraRAM 端口行为可以看作是 SDP 的超集,而不是 TDP。
- 固定读取行为; UltraRAM 没有用户可定义的先读、先写、不变模式。
- 静态数据级联; UltraRAM 没有动态级联输入或输出多路复用器控制。
- UltraRAM 不可能发生地址冲突。
- UltraRAM 级联数据、地址和控制信号,而不仅仅是数据线。
- 在UltraRAM 省电模式(SLEEP) 期间,只要满足设置和保持时间,用户操作将被忽略并且内容不会损坏。内存内容在睡眠省电模式下保留。
- 自动节能可以通过使用自动睡眠功能来实现,该功能可以根据活动独立控制唤醒和睡眠模式。该模式通过预测一列或多列中许多级联 UltraRAM 块的活动,动态地为链中选定的 UltraRAM 块打开或关闭睡眠模式。对于单个 UltraRAM 块应用程序,使用此功能需要许多不活动周期才能发挥作用。
不得违反 UltraRAM 地址、启用和睡眠引脚的时钟最小脉冲宽度和建立/保持时间。违反时钟最小脉冲宽度或这些设置/保持时间(即使写使能为低)可能会破坏 UltraRAM 的数据内容。这最常发生在时钟不稳定或驱动 UltraRAM 控制引脚的触发器被异步复位时,例如系统范围内的复位。为避免此问题,请确保时钟稳定,并为断言和反断言设计同步复位。当时钟不稳定时,禁用时钟缓冲器或禁用驱动 UltraRAM 控制引脚的逻辑或置低 UltraRAM EN 输入。
Memory 数组初始化方式
在 Verilog 中,对数组(memory)赋值可以通过几种不同的方式实现,具体取决于数组的类型和上下文。以下是一些常见的数组赋值方法:
直接赋值:
对于小的、静态的数组,可以直接使用数组名和索引进行赋值。
reg [7:0] mem[0:3]; // 定义一个4位宽,4深的寄存器数组
initial begin
mem[1] = 8'hA5; // 直接给数组的第二个元素赋值
end
循环赋值:
使用循环结构对数组的多个元素进行赋值。
initial begin
int i;
for (i = 0; i < 4; i = i + 1) begin
mem[i] = i * 4; // 使用循环给数组的每个元素赋值
end
end
文件输入:
使用 $readmemb 或 $readmemh 从文件中读取数据并赋值给内存数组。
reg [7:0] mem[0:1023]; // 定义一个4位宽,1024深的寄存器数组
initial begin
$readmemb("mem_file.bin", mem); // 从二进制文件中读取数据
// 或者
$readmemh("mem_file.hex", mem); // 从十六进制文件中读取数据
end
参数化赋值:
在模块实例化时,使用参数传递数组的初始值。
module my_module (
input [7:0] mem_array[0:3]
);
// 模块内部使用 mem_array
endmodule
// 在顶层模块中实例化并赋值
my_module my_mod_inst (.mem_array(mem));
使用 initial 块:
在 initial 块中,可以对数组进行初始化赋值。
initial begin
mem = 4'b0; // 对数组的所有位进行初始化赋值
end
使用 generate 语句:
使用 generate 和 for 循环来生成数组的赋值语句。
genvar i;
generate
for (i = 0; i < 4; i = i + 1) begin : gen_block
assign mem[i] = some_signal[i];
end
endgenerate
使用任务(tasks)或函数(functions):
定义任务或函数来对数组进行赋值操作。
task automatic set_mem;
input [3:0] value;
begin
mem = value;
end
endtask
// 调用任务
initial set_mem(4'b1);
标签:mem,UltraRAM,srl,寄存器,Xilinx,URAM,浅析,移位,赋值 From: https://blog.csdn.net/qq_40238141/article/details/141333444