Verilog的逻辑系统及数据类型(三):寄存器数组(Register Arrays)

微信公众号获取更多FPGA相关源码:
在这里插入图片描述

4.寄存器数组

4.1 寄存器数组声明

在Verilog中可以声明一个寄存器数组。

integer NUMS [7: 0]; // 包含8个整数数组变量
time  t_vals [3: 0];      // 4个时间数组变量

reg类型的数组通常用于描述存储器,其语法为:

reg [MSB:LSB] <memory_name> [first_addr:last_addr];

[MSB:LSB]定义存储器字的位数

[first_addr:last_addr]定义存储器的深度

例如:

reg [15: 0] MEM [0:1023]; // 1K x 16存储器
reg [7: 0] PREP [‘hFFFE: ’hFFFF]; // 2 x 8存储器

描述存储器时可以使用参数或任何合法表达式

parameter wordsize = 16;
parameter memsize = 1024;
reg [wordsize-1: 0] MEM3 [memsize-1: 0];

4.2 寄存器数组使用举例

以文章长短训练序列存储训练序列数剧为例:

OFDM802.11a的FPGA实现(十五)短训练序列:STS(含Matlab和verilog代码)

OFDM 802.11a的FPGA实现(十六)长训练序列:LTS(含Matlab和verilog代码)

STS一个周期的16个时域样值被存入片内ROM中,该ROM共有16个地址空间,每个地址对应16位的字长,其中高8位存储STS样值的虚部,低8位存储STS样值的实部(与IFFT输出保持一致)。ROM的地址信号由一个模161的计数器生成。STS_din_rdy作为ROM的读使能信号,代表后面的模块准备好接收数据。当STS_din_rdy为高时,计数器以模161形式开始计数161个时钟,生成的地址信号为计数器的低4位,即cnt[3:0]控制ROM将其中存储的16个STS样值重复读取10个周期,形成标准所规定的短训练序列。 代码如下:

assign En_cnt = STS_din_rdy & ~cnt_last;

counter #(.CNT_NUM('d161),
  .ADD(1'b1))
u_counter(
.clk  (clk    ), 
.rst_n  (rst_n    ),
.En_cnt  (En_cnt    ),      
.cnt  (cnt    ), 
.cnt_last (cnt_last   )
);

always @(posedge clk or negedge rst_n) 
 if(!rst_n)begin
  STS_dout_last <= 1'b0;
  STS_dout_Index <= 'd0;
 end
 else begin
  STS_dout_last <= cnt_last;
  STS_dout_Index <= cnt;
 end
  
always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin  //时域样值Im       Re
        Short_Mem[0]  <= {8'b00011000,8'b00011000};      
        Short_Mem[1]  <= {8'b00000001,8'b10111100};
        Short_Mem[2]  <= {8'b11011000,8'b11111001};
        Short_Mem[3]  <= {8'b11111010,8'b01001001};
        Short_Mem[4]  <= {8'b00000000,8'b00101111};
        Short_Mem[5]  <= {8'b11111010,8'b01001001};
        Short_Mem[6]  <= {8'b11011000,8'b11111001};
        Short_Mem[7]  <= {8'b00000001,8'b10111100};
        Short_Mem[8]  <= {8'b00011000,8'b00011000};
        Short_Mem[9]  <= {8'b10111100,8'b00000001};
        Short_Mem[10] <= {8'b11111001,8'b11011000};
        Short_Mem[11] <= {8'b01001001,8'b11111010};
        Short_Mem[12] <= {8'b00101111,8'b00000000};
        Short_Mem[13] <= {8'b01001001,8'b11111010};
        Short_Mem[14] <= {8'b11111001,8'b11011000};
        Short_Mem[15] <= {8'b10111100,8'b00000001};
  STS_dout <= 'd0;
  STS_dout_vld <= 1'b0;
 end
 else if(STS_din_rdy & STS_dout_last)
  STS_dout_vld <= 1'b0;
 else if(cnt == 'd0 | cnt_last)begin
  STS_dout <= {Short_Mem[0][15:8]>>1,Short_Mem[0][7:0]>>1};
  STS_dout_vld <= 1'b1;
 end
 else begin
  STS_dout <= Short_Mem[cnt[3:0]]; 
  STS_dout_vld <= 1'b1;
 end
end

微信公众号获取更多FPGA相关源码:
在这里插入图片描述

好的,我可以帮你解答这个问题。 首先,寄存器组是由多个寄存器组成的集合。在Verilog中,我们可以使用reg类型来定义寄存器。 以下是一个寄存器组的Verilog代码示例: ```verilog module register_file( input clk, input [4:0] read_reg1, input [4:0] read_reg2, input [4:0] write_reg, input [31:0] write_data, input write_enable, output [31:0] read_data1, output [31:0] read_data2 ); reg [31:0] regs [31:0]; // 定义一个包含32个32位寄存器寄存器组 always @(posedge clk) begin if (write_enable) // 写使能信号为1时,将write_data写入到write_reg所指定的寄存器中 regs[write_reg] <= write_data; end assign read_data1 = regs[read_reg1]; // 从read_reg1所指定的寄存器中读取数据 assign read_data2 = regs[read_reg2]; // 从read_reg2所指定的寄存器中读取数据 endmodule ``` 在这个示例中,我们定义了一个名为register_file的模块,其中包含5个输入:时钟信号clk、两个读寄存器的地址read_reg1和read_reg2、一个写寄存器的地址write_reg、一个写数据write_data和一个写使能信号write_enable;以及两个输出read_data1和read_data2,这两个输出分别从read_reg1和read_reg2所指定的寄存器中读取数据。 在always块中,我们使用if语句来判断写使能信号是否为1,如果是1,则将write_data写入到write_reg所指定的寄存器中。在assign语句中,我们将read_data1和read_data2分别赋值为从read_reg1和read_reg2所指定的寄存器中读取的数据。 这是一个简单的寄存器组实现示例,你可以根据需要修改和扩展它。希望能对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值