(Sistema) Verilog: ¿extrayendo un bus / vector más pequeño de un bus más grande?

0

¿Cuál es la mejor práctica para crear un bus, que es solo la extracción de ciertos bits de un bus más grande? No quiero almacenar los números de índice para realizar la búsqueda en el programa generar si se pudiera evitar ... Esperaba algo como seguir el código que, por supuesto, no es válido. ¿Podemos aprovechar el hecho de que el bus más corto extraído es siempre bits consecutivos del bus más grande?

localparam logic [7:0] VALID = {1'b0, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0, 1'b0, 1'b0}; 


 genvar m, j;
  generate
    for (m=0; m<8; m++) begin
      if (VALID[m]) begin
        assign short_bus[j] = large_bus[m];
        j++;
      end
  endgenerate
    
pregunta frank_010

2 respuestas

0

Tienes varias opciones en SystemVerilog.

Si sus buses son redes, puede usar una construcción alias (consulte la sección 10.11 del LRM 1800-2017)

alias long_bus[M:N] = short_bus;
alias long_bus[O:+W] = short_bus;

M,N,O , y W deben ser expresiones constantes de literales o parámetros. Para variables o redes, puede usar el constructo let (consulte la sección 11.12)

let short_bus = long_bus[M:N];
let short_bus = long_bus[O+:W]; // O does not need to be a constant

Los beneficios de estas construcciones sobre la construcción assign es que es posible usar short_bus tanto en el LHS como en el RHS de una asignación.

    
respondido por el dave_59
0

Usaría una matriz con la longitud del bus corto que asigna índices de bus cortos a los de bus grande:

// Large Bus Width
localparam int LBW = 8;
localparam logic [LBW-1:0] VALID = {1'b0, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0, 1'b0, 1'b0};

// 1. Function returning the width of the short bus
function automatic int get_short_width();
    automatic int si = 0;
    for (int li=0; li<LBW; li++)
        if (VALID[li])
            si++;
    return si;
endfunction

// Short Bus Width
localparam int SBW = get_short_width();

typedef int t_idx_arr[SBW];
// 2. Function returing the large-to-short array index mapping
function automatic t_idx_arr get_short_indices();
    t_idx_arr idx_ret;
    automatic int si = 0;

    for (int li=0; li<LBW; li++) begin
        if (VALID[li]) begin
            idx_ret[si] = li;
            si++;
        end
    end
    return idx_ret;
endfunction

// Large 2 Short Index Array
localparam t_idx_arr L2S_IDX = get_short_indices();

// 3. Assign
logic[LBW-1:0] large_bus;
logic[SBW-1:0] short_bus;

// note: loop on the SHORT bus width!
for (genvar si=0; si<SBW; si++) begin
    assign short_bus[si] = large_bus[L2S_IDX[si]];
end

assign large_bus = 8'b1101_1011;
// short_bus = 4'b1011

Esto también funciona para posiciones de bit válidas no consecutivas en el bus grande.

    
respondido por el rascob

Lea otras preguntas en las etiquetas