您如何 select 寄存器表达式中的一系列位?
How do you select a range of bits from an expression of registers?
我正在尝试取 8 个 8 位寄存器的平均值。通过使用四个 8-> 9 位加法器、两个 9-> 10 位加法器和一个 10-> 11 位加法器,我能够在结构上做到这一点。这工作正常;但是,我很好奇是否有更好的方法/更有效的方法来做到这一点。
对于结构方式,我所要做的就是从 10->11 位加法器到输出分配一条线。
我正在尝试执行如下操作,但它显示
索引 <10> 超出信号范围 [7:0]。
我有它的索引 10,以防所有寄存器都像 255 这样大。
module avg(
num_in,
clk,
rs,
ave8
) ;
input clk ;
input rs;
input [7:0] num_in ;
output [7:0] ave8 ;
reg [7:0] registers [7:0] ;
always @(posedge clk) begin
if(rs) begin
registers[0] <= 0;
registers[1] <= 0;
registers[2] <= 0;
registers[3] <= 0;
registers[4] <= 0;
registers[5] <= 0;
registers[6] <= 0;
registers[7] <= 0;
end
registers[0] <= num_in;
registers[1] <= registers[0];
registers[2] <= registers[1];
registers[3] <= registers[2];
registers[4] <= registers[3];
registers[5] <= registers[4];
registers[6] <= registers[5];
registers[7] <= registers[6];
end
// This assign function is what I am focused on.
assign ave8 = {registers[0] + registers[1] + registers[2] + registers[3] + registers[4] + registers[5] + registers[6] + registers[7]}[10:3];
一种方法是创建 sum
线:
wire [10:0] sum = registers[0] + registers[1] + registers[2] + registers[3] + registers[4] + registers[5] + registers[6] + registers[7];
assign ave8 = sum[10:3];
我建议使用 for
循环:
module avg(
input [7:0] num_in ,
input clk ,
input rs ,
output reg [7:0] ave
);
parameter SIZE = 8;
reg [7:0] registers [SIZE-1:0] ;
reg [10:0] accumulator;
integer i;
always @(posedge clk) begin
if(rs)
for(i=0;i<SIZE;i=i+1)
registers[i] <= 0;
registers[0] <= num_in;
for(i=1;i<SIZE;i=i+1)
registers[i] <= registers[i-1];
accumulator = 0;
for(i=0;i<SIZE;i=i+1)
accumulator = accumulator + registers[i];
ave <= accumulator/SIZE;
end
endmodule
用 ISE 支持的 SystemVerilog 编写会容易得多:
module avg(
input [7:0] num_in ,
input clk ,
input rs ,
output logic [7:0] ave
);
parameter SIZE = 8;
logic [7:0] registers [SIZE] ;
always @(posedge clk) begin
if(rs)
registers = '{default:0};
registers <= {num_in, registers[1:$size(registers)-1]};
ave <= registers.sum() with (int'(item))/SIZE;
end
endmodule
我正在尝试取 8 个 8 位寄存器的平均值。通过使用四个 8-> 9 位加法器、两个 9-> 10 位加法器和一个 10-> 11 位加法器,我能够在结构上做到这一点。这工作正常;但是,我很好奇是否有更好的方法/更有效的方法来做到这一点。
对于结构方式,我所要做的就是从 10->11 位加法器到输出分配一条线。
我正在尝试执行如下操作,但它显示
索引 <10> 超出信号范围 [7:0]。 我有它的索引 10,以防所有寄存器都像 255 这样大。
module avg(
num_in,
clk,
rs,
ave8
) ;
input clk ;
input rs;
input [7:0] num_in ;
output [7:0] ave8 ;
reg [7:0] registers [7:0] ;
always @(posedge clk) begin
if(rs) begin
registers[0] <= 0;
registers[1] <= 0;
registers[2] <= 0;
registers[3] <= 0;
registers[4] <= 0;
registers[5] <= 0;
registers[6] <= 0;
registers[7] <= 0;
end
registers[0] <= num_in;
registers[1] <= registers[0];
registers[2] <= registers[1];
registers[3] <= registers[2];
registers[4] <= registers[3];
registers[5] <= registers[4];
registers[6] <= registers[5];
registers[7] <= registers[6];
end
// This assign function is what I am focused on.
assign ave8 = {registers[0] + registers[1] + registers[2] + registers[3] + registers[4] + registers[5] + registers[6] + registers[7]}[10:3];
一种方法是创建 sum
线:
wire [10:0] sum = registers[0] + registers[1] + registers[2] + registers[3] + registers[4] + registers[5] + registers[6] + registers[7];
assign ave8 = sum[10:3];
我建议使用 for
循环:
module avg(
input [7:0] num_in ,
input clk ,
input rs ,
output reg [7:0] ave
);
parameter SIZE = 8;
reg [7:0] registers [SIZE-1:0] ;
reg [10:0] accumulator;
integer i;
always @(posedge clk) begin
if(rs)
for(i=0;i<SIZE;i=i+1)
registers[i] <= 0;
registers[0] <= num_in;
for(i=1;i<SIZE;i=i+1)
registers[i] <= registers[i-1];
accumulator = 0;
for(i=0;i<SIZE;i=i+1)
accumulator = accumulator + registers[i];
ave <= accumulator/SIZE;
end
endmodule
用 ISE 支持的 SystemVerilog 编写会容易得多:
module avg(
input [7:0] num_in ,
input clk ,
input rs ,
output logic [7:0] ave
);
parameter SIZE = 8;
logic [7:0] registers [SIZE] ;
always @(posedge clk) begin
if(rs)
registers = '{default:0};
registers <= {num_in, registers[1:$size(registers)-1]};
ave <= registers.sum() with (int'(item))/SIZE;
end
endmodule