Tengo una placa Spartan 3-E. Estaba usando el Xilinx SRL 16 incorporado (registros de turnos concatenados de 16 bits) para la comunicación I2C. Verifiqué la implementación exitosa mostrando el número de "Acks" recibidos en los LED, es decir (tuve un contador interno que aumentaría si el SDA se agotara durante el noveno ciclo de reloj). Mi problema comienza cuando en lugar de usar la primitiva SRL de Xilinx, construí mi registro personalizado de 8 bits a la izquierda. Tenía que hacer esto porque el sistema tenía que ser mantenido inactivo durante algún tiempo y solo es necesario programar algunos registros específicos, por lo que no puedo confiar en la función de incremento automático. De cualquier manera, no he podido verificar la comunicación I2C. como antes, a pesar de mantener todos los demás aspectos iguales y asegurar una diferencia absolutamente nula entre los patrones de simulación del diseño anterior exitoso y este nuevo. Estoy compartiendo mi código y estaría extremadamente agradecido a cualquiera que pueda echarle un vistazo.
------------------ SRL de 8 bits ----------------
module CustomSRL(
input [7 : 0] Value,
input LE,
input CE,
input clk_i2c,
output Q
);
reg [7 : 0] SRL_8;
always @ (posedge clk_i2c)
begin
if(CE) begin
if(LE) SRL_8 <= Value;
else SRL_8 <= {SRL_8[6 : 0],1'b0};
end
end
assign Q = SRL_8[7];
endmodule
ACTUALIZACIÓN:
Estaba experimentando y me di cuenta de que cuando sustituyo mi Shift Register personalizado (provisto arriba) con la primitiva SRL16 E, el diseño funciona. Esto es muy sorprendente. Traté de hacer pequeños cambios en la lógica utilizando un simple registro con un Load Enable y un multiplexor para seleccionar los bits. Sin embargo, eso tampoco funciona.
¿Por qué funciona el diseño primitivo SRL16E pero no los otros? He proporcionado el código para mi módulo de registro de desplazamiento (entrada de serie, salida de serie, carga síncrona paralela) anterior. Los resultados de la simulación son los mismos para los tres diseños.
¿Alguien puede ofrecer una explicación para este comportamiento aparentemente extraño? Enviando valores a 8 bit Shift Register:
always @ (*)
begin
case (Byte_Counter)
0 : LUT <= 8'h56; //Device Addres
1 : LUT <= i2c_address; //Register Address
2 : LUT <= i2c_val; //Data
5 : LUT <= 8'h7E; //STOP & START
default : LUT <= 8'hFF;
endcase
end
always @ (*)
begin
case (Reg_Counter)
1 :begin i2c_address <= 8'h00; i2c_val <= 8'h02; end
2 :begin i2c_address <= 8'h03; i2c_val <= 8'h00; end
3 :begin i2c_address <= 8'h05; i2c_val <= 8'h09; end
4 :begin i2c_address <= 8'h07; i2c_val <= 8'h07; end
5 :begin i2c_address <= 8'h09; i2c_val <= 8'h00; end
default : begin i2c_address <=8'h00; i2c_val <= 8'h00; end
endcase
end
La LUT variable se carga en el registro de desplazamiento de 8 bits en el noveno (cuando SDA = alta impedancia) ciclo de reloj.
Una cosa que me gustaría agregar es que traté de registrar las salidas de los multiplexores antes de empaquetarlo en la SRL de 8 bits por:
always @ (posedge clk_i2c) temp <= LUT;
Sin embargo, eso tampoco ha funcionado, pero recibí una advertencia interesante:
INFO:Xst:2260 - The FF/Latch <i2c_ADV7171/temp_6> in Unit <Verilog> is equivalent to the following FF/Latch : <i2c_ADV7171/temp_4>
Por lo que puedo decir, esto no debería ocurrir porque la temperatura [6] y la temperatura [4] no son iguales en todos los aspectos.