Defining an array in verilog down to a nonzero constant - arrays

I have the following sub-module:
module test
(
input [LENGTH : 1] array;
);
...
endmodule
And I'm calling it from a top module as follows:
...
wire [LENGTH-1 : 0] array_top;
test test_i
(
.array (array_top);
);
...
Assume LENGTH is the same in both modules.
How will array_top map to array, given array_top goes down to zero but array goes to down 1?
Why would anyone define an array down to 1 and not down to 0?
What will happen to array[0]?
Thanks,

Your questions can be answered with a small testbench:
module tb;
reg [3:0] atop;
initial begin
$monitor("array_top=%b, array=%b", array_top, test_i.array);
#1 atop = 4'b0000;
#1 atop = 4'b0001;
#1 atop = 4'b0010;
#1 atop = 4'b0100;
end
wire [3:0] array_top = atop;
test test_i (.array (array_top));
endmodule
module test (input [4:1] array);
endmodule
Output:
array_top=xxxx, array=xxxx
array_top=0000, array=0000
array_top=0001, array=0001
array_top=0010, array=0010
array_top=0100, array=0100
From your connection: array[1] = array_top[0], etc.
Sometimes people want to omit connecting a signal's LSB, like an address for a memory, because the LSB has no effect.
There is no array[0] signal.

When connecting ports, Verilog only cares that arrays have the same size (called an equivalent type in SystemVerilog) It does not care about the starting index value, or whether it increases or decreases. It will start by connecting the right range (LSB) of each signal. In your case array_top[0] connects to array[1]. If the sizes do not match you may get an error or warning, depending on the tool and its settings. Then the connection will either be padded or truncated after hitting the left range (MSB).

Related

syntax error in accessing 2d register array in verilog code to synthesize in leonardo tool

I made a simple cache with verilog code in ISE tool, and used a 2d array of registers as my cache memory, simulating testbench on it in Modelsim done well and no syntax errors and no mistake in desires output signals, but in Leonardo tool when I tell Leonardo read it in library ams600nm it return syntax error near first line that I accessed my 2d array (cache), do you have any idea?
code:
module Cache(clk , wr
,din,adr,dout
);
input clk;
input wr;
input [3:0] din;
input [3:0] adr;
output [3:0] dout;
output hit;
reg [8:0] cache [3:0];
reg h;
reg [3:0] out;
initial
begin
***cache[0][8] = 1'b0; -----here-----
cache[1][8] = 1'b0; -----also here for sure-----
cache[2][8] = 1'b0;
cache[3][8] = 1'b0;***
end
You don't have output hit in module port list.
You don't have endmodule keyword.
Some software allow to access only all bits in array's row. I don't have access to your software, so I can't test it, but you should try something like that:
temp = cache[0];
cache[0] = {1'b 0, temp[7:0]};
This is equivalent to:
cache[0][8] = 1'b0;
temp should be declared as reg [8:0] temp; (same width as cache).

how to do acircular shift for an array via verilog

In C language, there is an array x[0], x[1], ..., x[127], for a given number k in [0, 127), we difine left shift operation as y[n] = x[(n+k)%128], for n=0,1,2...,127
Now I am try to implement this in FPGA, as there are so many this type operations, I like to get the result as fast as possile.
I did this as follows,
module LEFT_SHIFT(
input clk,
input rst,
input [31:0] data_in[0:127])
input [6:0] shift,
output reg [31:0] data_ou[0:127]
);
integer i;
always # (posedge clk)
begin
if (rst)
for (i=0;i<128;i++)
data_out[i] <= 32'bb0;
else
for (i=0;i<128;i++)
data_out[(i+shift)%128] = data_in[i];
end
endmodule
Is this code fine in terms speed, resource and timing? I looks like a RAM, but RAM does't output all the memory at the same time.
Many thanks,
Jerry
If you replace the Mod operator (%) with a replication of the input data to make the circular shift you could make the task easier for the compiler. I tried this on the synthesis tool from a major ASIC tool vendor and the results were quite different.
if (rst)
for (integer i=0;i<128;i++)
data_out[i] <= 32'b0;
else begin
logic [31:0] tmp [0:255];
for (integer i=0;i<128;i++) begin
// replicate input data
tmp[i] = data_in[i];
tmp[i+128] = data_in[i];
end
for (integer i=0;i<128;i++)
data_out[i] <= tmp[128-shift+i];
end
That's a huge mux that will consume a lot of logic resources in the FPGA. I've seen things like that crash the tools before. You may want to consider adding more than just one register in there.
As far as speed, resource, and timing goes, it depends on how fast you want it to run and how many free resources you have. It could be fine at low speed on a big FPGA or impossible at higher speeds or small/full FPGA. But there's no need to speculate about resource and timing, just build it and see what happens.

VHDL Comparison Operation Not Defined with Looping Counter

I've been trying to make an SRAM chip in vhdl with arbitrary amount of registers and register size using generics and I've almost gotten it to work except for the addressing part.
To make an arbitrary sized SRAM chip I started by making a unit SRAM Cell (which I tested to confirm that it works) with the following port map.
component SRAM_Cell_vhdl
port (
IN : in std_ulogic;
Select_Chip : in std_ulogic;
Write_Enable : in std_ulogic;
Out1 : out std_ulogic
);
The generic SRAM chip has the following port map:
port (
Datain : in std_logic_vector(m-1 downto 0);
address: in std_logic_vector(n-1 downto 0);
Chip_Select: in std_logic;
Output_Enable: in std_logic;
Write_Enable: in std_logic;
Out2: out std_logic_vector(m-1 downto 0)
);
The way I'm trying to do the addressing is that when it generates the SRAM it checks if the loop counter is equal to the address. If it is it will write the bit to the SRAM cell, if not it will not.
loop1: for I in 0 to n-1 generate
loop2: for J in 0 to m-1 generate
SRAM_Cell_vhdl1 : SRAM_Cell_vhdl port map
(Datain(J), Chip_Select and (I = to_integer(unsigned(address))), Write_Enable and Chip_Select, intermediate_out(I, J));
end generate loop2;
end generate loop1;
However, I am getting an error at I = to_integer(unsigned(address))) telling me that it can't determine the definition of the operation "=". I thought that a loop counter is an integer and the way I'm converting the address to an integer it should be doing a comparison between two integers. The other way I thought of doing this is to use an if statement comparing I and the address, but then I fear that it will not generate all of the required SRAM cells.
Is there a way to solve this problem?
The = operator returns a boolean. So, the expression
Chip_Select and (I = to_integer(unsigned(address)))
when associated with an input port of type std_ulogic requires a version of the and operator with an input of type std_ulogic, an input of type boolean and a return value of type std_ulogic. (This list of types is called its signature). No such version of the and operator exists.
There is a version of theand operator that with two inputs of type std_ulogic and a return value of type std_ulogic. So, in order to use that, your compiler is trying to find a version of the = operator that returns a std_ulogic. No such version exists. Hence your error.
Solving this problem is not straight forward, because you'll need an array of chip select signals. So, you'll need something like this (as there's no MCVE, I haven't tested it):
loop1: for I in 0 to n-1 generate
loop2: for J in 0 to m-1 generate
if Chip_Select = '1' and (I = to_integer(unsigned(address))) then
CS(I)(J) <= '1';
else
CS(I)(J) <= '0';
end if;
SRAM_Cell_vhdl1 : SRAM_Cell_vhdl port map (Datain(J), CS(I)(J), Write_Enable and Chip_Select, intermediate_out(I, J));
end generate loop2;
end generate loop1;
where CS is some kind of array of std_ulogic.
Firstly, your code is not MCVE. It would have been more helpful if it was. I guess the below alternative should work.
loop1: for I in 0 to n-1 generate
loop2: for J in 0 to m-1 generate
signal2 <= Write_Enable and Chip_Select;
check1: if (I = to_integer(unsigned(address))) generate
signal1 <= Chip_Select and std_ulogic(unsigned(address));
end generate check1;
SRAM_Cell_vhdl1 : SRAM_Cell_vhdl port map (Datain(J), signal1 , signal2 , intermediate_out(I, J));
end generate loop2;
end generate loop1;
Also, I would prefer using named association rather than positional association in port map

In verilog Part-select of vector reg array is illegal

reg [data_width-1:0]coeff[0:order-1];
wire[3:0]lsbcoeff;
wire [7:4]msbcoeff;
lsbcoeff = coeff[3:0];
msbcoeff = coeff[7:4];
In the above line of code, im getting error
Part-select of vector reg array 'coeff' is illegal
Illegal right hand side of blocking assignment
Please guide me , how to overcome this ?
Xilinx v14.2
Verilog coding
You have coeff defined as a vector of coefficients, I am not sure what you expect coeff[3:0] to return? a vector of the LSBS? I think what you intended was something like coeff[0][3:0] Selecting the LSBs of the first vector. Code below shows a possible way of doing this:
module tb;
localparam data_width = 8;
localparam order = 2;
reg [data_width-1:0]coeff[0:order-1];
reg [3:0] lsbcoeff;
reg [7:4] msbcoeff;
reg [7:0] this_coeff;
always #* begin
lsbcoeff = coeff[0][3:0];
msbcoeff = coeff[0][7:4];
end
endmodule
and now I have read the comments I see this is what #Greg has already suggested.
In addition to #Morgan code, the wire should be assigned value using assign statement in verilog.
always #(*) begin
assign lsbcoeff = coeff[0][3:0];
assign msbcoeff = coeff[0][7:4];
end

Forward error correction using Reed-Solomon Erasure Correction

I have the task of encoding and decoding some bytes of sound using parity checksum method and Reed-Solomon Erasure Correction.
I've done my encoding for first method(parity checksum) but need help completing the second method which is detection by Reed-Solomon Erasure Correction.
So far I know that, RS code adds t symbols to k symbols of data. So it is able to locate and correct up to t/2 symbols or if the error locations are known so called erasures. It can correct up to t. For this task I have to use Galois field GF(28) to represent each symbol as a byte. Operation addition and subtraction are based on XOR. So over all I have to employ Reed-Solomon codes that are capable of correction up to t=3 erasures. The computation of a single Reed Solomon code in now as follow
C0 | C1 |........| Ck-1 | Ck | Ck+1 | Ck+2
so the code bytes can be viewed as vector c=[c0,c1,...,ck+2]
and a single code C is computed from k bytes of data as follow
d=[d0,d1,...,dk-1], so my encoding and decoding process require the following Vandermonde matrix F
1 1 12 13 ... 1k-1
1 2 22 23 ... 2k-1
...
1 k+2 (k+2)2 (k+2)3 ... (k+2)k-1
1 k+3 (k+3)2 (k+3)3 ... (k+3)k-1
so a simple matrix vector multiplication using F & D we get C=F.D.
so far what I did for encoding is as follow :
#else
void fox_encode(Buffer* bufin, Buffer* bufout, FoxEncData* algorithm_data){
// Your encoder for Task 2.C.3 goes in here !!!
while (bufin->size >= 1){
guint8 databyte = bufin->data[0]; //Pick up a byte from input buffer
buffer_push_byte (bufout, databyte); //Send it 3 times
buffer_push_byte (bufout, databyte);
buffer_push_byte (bufout, databyte);
buffer_pop (bufin, 1); //Remove it from the input buffer
}
}
#endif
I need code to complete this code for encoding and decoding my fox_encode and fox_decode class using Reed-Solomon Erasure Correction. Any Help will be appreciated to complete this task as soon as possible.
Thanks in advance
You can take look at my RS(255,255-k) C-implementation which is available from my homepage.
It handles both errors and erasures and corrects any byte error/erasure patterns bounded by:
(2*errorCount + erasureCount) <= k.
There is now a good tutorial on Wikiversity which details how to handle both erasures and errors.
Here is an outline of what you need to implement for the erasures decoding process:
Compute the syndromes. Then check if it's all 0 coefficients, the message does not need correction, else continue.
Call the Forney algorithm with the syndrome and the erasures positions as input to compute the erasure magnitude polynomial (ie, the values to subtract from message polynomial to get the original message back).
Subtract message - erasure_magnitude_polynomial to recover your original message (if within Singleton bound).
Apart from the Forney algorithm which can be a bit involving, all the other parts are very simple and straightforward. Indeed, the most difficult parts such as Berlekamp-Massey algorithm and Chien search are only necessary when you want to decode errors, and Forney syndromes computation is only necessary if you want to correct both erasures and errors (ie, errata) -- although I have read some paper which describe that Forney syndromes computation can be bypassed, but I never seen such a code.

Resources