(Tengo dos preguntas para ti al final.)
Estoy usando SystemVerilog para hacer varios ejercicios (para edificación personal) en el capítulo 7 de Diseño digital y arquitectura de computadora . Estoy usando Quartus II 13.1.2 Web Edition de Altera y ModelSim Altera Starter Edition 10.1d (Revisión 2012.11 con fecha 2 de noviembre de 2012) para el software en Windows 7 x64, y mi hardware no es relevante en este momento (aunque es un Altera DE2-115).
Una cosa que tengo que hacer es decodificar una señal logic
de 32 bits en varios campos diferentes para poder decodificar instrucciones. Hay tres posibilidades de decodificación separadas para las instrucciones MIPS de 32 bits que utiliza el libro. Entonces, hice packed
struct
s por separado para cada uno:
typedef struct packed {
logic [5:0] op;
logic [4:0] rs, rt, rd, shamt;
logic [5:0] funct;
} instruction_r;
typedef struct packed {
logic [5:0] op;
logic [4:0] rs, rt;
logic [15:0] imm;
} instruction_i;
typedef struct packed {
logic [5:0] op;
logic [25:0] addr;
} instruction_j;
Cuando intenté convertirlos en union
, descubrí que Quartus II no admite union
s. Drat.
Entonces, hice otro typedef
y usé un poco de casting para hacer que todos fueran iguales, solo que con diferentes nombres:
typedef logic [31:0] instruction;
// usage in a module...
instruction logic_instr;
instruction_r instr;
instruction_i instr_i;
instruction_j instr_j;
assign instr = logic_instr;
assign instr_i = instruction_i'(instr);
assign instr_j = instruction_j'(instr);
Esto funciona tanto en Quartus II como en ModelSim.
Sin embargo, la necesidad del tipo instruction
adicional fue para solucionar un problema que ModelSim me dio y que no molestó a Quartus II. En este siguiente recorte, la primera declaración funciona en ambos, pero la segunda solo funciona en Quartus II.
// Works in both
floper #(32) instruction_reg(clk, reset, c_irwrite, readdata, logic_instr);
// Works only in Quartus II (and allows me to remove the logic_instr entirely)
floper #(32) instruction_reg(clk, reset, c_irwrite, readdata, instruction'(instr));
// For reference: Enabled, resettable flipflop
module floper #(parameter WIDTH = 8)
(input logic clk, reset, en,
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
// ...
endmodule
El error que da ModelSim es "(vsim-3053) Salida ilegal o conexión de puerto de entrada para el" puerto 'q' ". No da el error en el momento de la compilación, solo el tiempo de simulación.
Mis preguntas para StackExchange son:
-
¿Existe una forma más elegante de tener una variable
logic [31:0]
a la que se pueda hacer referencia fácilmente por varios subconjuntos de sus cables sin pasar por todo este rigamarole verboso? -
¿Existe una sintaxis que pueda usar con Quartus II y ModelSim que me permita evitar tener otra variable adicional al enviar el
struct instruction_r
(oi
oj
) a un módulo que espera unlogic [31:0]
?
Estoy seguro de que tiene que haber una mejor manera de hacer este tipo de cosas, ya que parece algo que probablemente sea muy común en cualquier tipo de diseño a gran escala.
¡Gracias!