Esto es algo importante para entender. Verilog es un lenguaje de descripción de hardware, lo que significa que lo que está haciendo no es escribir código en los arreglos 2D de acceso y, por lo tanto, está escribiendo código que describe qué hardware se requiere. En algo como C (un lenguaje de procedimiento), la inicialización de una matriz es algo que se realiza en tiempo de ejecución: la CPU copia el contenido de la matriz de la memoria del programa a la RAM y luego puede usarla. Sin embargo aquí no tienes ese paso.
Además, la sintaxis que está intentando usar es algo de C, no de Verilog. De hecho, en Verilog, {}
significa concatenación. Entonces, en esencia, lo que está haciendo es concatenar diez valores de 16 bits en un único vector de 160 bits. Entonces intenta asignarlo como el valor de inicialización a una RAM que no es del mismo tamaño. ¿Cómo encaja un vector 1x160 en una memoria de 10x16bit?
También tenga en cuenta que su registro se declara de tamaño incorrecto; usted dice que lo desea con 16 bits, pero que ha hecho de cada uno 17 bits ([16: 0] = 17b).
Tienes dos opciones a considerar.
Opción 1
La primera opción es dividir las cosas un poco. En lugar de intentar hacer todo de una vez, considere lo que hace su hardware. En esencia, lo que tiene no es una RAM, sino dieciséis registros de desplazamiento circular de 10 bits. Todos trabajan sincronizados entre sí, sí, pero en realidad son dieciséis copias del mismo hardware, así que trabajemos con eso. ¿Cómo hacemos dieciséis copias idénticas de algo? Dos opciones, crear un módulo e instanciarlo dieciséis veces, o más simplemente usar algo llamado generate
loop: es básicamente un bucle for que instancia múltiples copias de hardware. Vamos a usar la segunda opción.
parameter INITIAL_VALUE = {16'h0,16'h1,16'h2,16'h3,16'h4,16'h5,16'h6,16'h7,16'h8,16'h9}; //Concatenate our initial values into a single parameter.
genvar j; //This is our generate loop variable.
generate for (j = 0; j < 16; j=j+1) begin : shift_reg_loop //shift_reg_loop is just a name for the loop. It can be any valid HDL name.
//Now we instantiate one 10bit circular shift register
reg [9:0] byteShiftReg; //Just 1 bit of the 16.
integer i;
initial begin
for (i=0;i<9;i=i+1) begin
byteShiftReg[i] = INITIAL_VALUE[i*16+j]; //Initialise each bit with the correct value extracted from our initial value.
end
end
always @ (posedge CLK) begin
BYTE_OUT[j] <= byteShiftReg[0];
for (i=0;i<9;i=i+1) begin
byteShiftReg[i] <= byteShiftReg[i+1];
end
byteShiftReg[9] <= BYTE_OUT[j];
end
end endgenerate //end of for loop and generate statement.
Opción 2
Habiendo dicho todo lo anterior, en realidad, en su caso, realmente no necesita dividir las cosas, pero primero quería presentarles la opción de darle una idea de lo que está pasando debajo del capó, por así decirlo. y le dará información útil para futuros trabajos.
Podemos usar una de las cosas que introduje en el otro ejemplo para inicializar la memoria directamente, el llamado bloque initial
. Esto te permite hacer varias cosas "al principio". Recuerda cómo dije que para un programa de C, la inicialización de la matriz se realiza en tiempo de ejecución. Bueno, en Verilog es posible hacer algo similar pero en síntesis . En otras palabras, podemos inicializar la matriz indicando al sintetizador cuál será el valor predeterminado para cada registro (valor de encendido).
Para grupos multidimensionales de registros, como memorias, podemos definir un bloque inicial que puede hacer cosas muy similares a su bloque siempre. En este caso para bucles.
parameter initialValue = {16'h0,16'h1,16'h2,16'h3,16'h4,16'h5,16'h6,16'h7,16'h8,16'h9}; //This works because concatenation makes it a 160bit wide value.
reg [15:0] byteShiftReg[9:0];
initial begin
for (i=0;i<9;i=i+1) begin
//Extract each 16bit chunk in turn from the initial value parameter
//and use that as the initial value for this part of the shift register.
// Note the (9-i) bit is used because concatenation of the initial value places the first value in the most significant bits, and last value in the least significant bits.
byteShiftReg = initialValue[((9-i)*16)+:16];
end
end
integer i;
always @(posedge CLK)
begin
BYTE_OUT <= byteShiftReg[0];
for (i=0;i<9;i=i+1) begin
byteShiftReg[i] <= byteShiftReg[i+1];
end
byteShiftReg[9] <= BYTE_OUT;
end
endmodule