Estoy intentando crear VHDL sintetizable que desmultiplexará un flujo de señal continuo de un bit a una de muchas salidas. Las salidas que no se envían a esta secuencia deben establecerse en '0'. Vea la imagen a continuación para tener una idea de lo que estoy tratando de lograr.
El código que he escrito para crear esta funcionalidad es:
send_s <= (line_select_s => prbs_i(0), others => '0');
donde 'prbs_i(0)' es el flujo de señal.
Desafortunadamente, esto no se puede sintetizar en Vivado, dando el error:
[Synth 8-211] could not evaluate expression: aggregate choice expression
¿Hay una manera adecuada de hacer esto? El VHDL simula bien pero no sintetiza.
El problema con su código es que una asignación de la forma:
a <= (3 => '0', others => '1');
debe usar constantes para las compensaciones que se asignan (en este caso, 3).
Si necesita que el desplazamiento se configure para que varíe, debe dividirlo en dos asignaciones. Tenga en cuenta que esto solo funcionará dentro de un proceso; con un par de asignaciones concurrentes, encontraría un problema de controlador múltiple.
process (line_select_s, prbs_i)
begin
send_s <= (others => '0');
send_s(line_select_s) <= prbs_i(0);
end process;
Esto funciona porque aunque comencemos asignando '0'
a todo el vector, tendrá prioridad la última asignación a una señal en particular en un proceso.
Una alternativa es usar un bucle:
process (line_select_s, prbs_i)
begin
send_s <= (others => '0');
for i in send_s'range loop
if (i = line_select_s) then
send_s(i) <= prbs_i(0);
end if;
end loop;
end process;
Esto tiene la ventaja de que si su señal seleccionada puede representar un desplazamiento mayor que el ancho de su vector objetivo, no se producirá ningún error en la simulación. Un escenario de ejemplo sería una señal de selección de 3 bits, pero un vector objetivo con solo 5 elementos; el primer método produciría un error si la señal de selección representara 6, 7 u 8, pero el segundo no.
Como nota al margen, es posible que desee realizar un proceso como este sincrónico si desea obtener el mejor rendimiento (en términos de frecuencia operativa máxima) de su diseño.
Hay muchas maneras. Una forma sencilla de hacerlo es, por modelo de flujo de datos:
with line_select_s select
send_s <= (send_s & "0000") when "000",
('0' & send_s & "000") when "001",
("00" & send_s & "00") when "010",
("000" & send_s & '0') when "011";
("0000" & send_s) when "100";
"00000" when others;
usuario_1818839
send_s(line_select_s) <= prbs_i(0);
: recuerde que este proceso tiene que generar hardware para permitir que cualquier salida transporte la señal (de ahí el bucle), y solo controle la seleccionada (de ahí el si). El loop se desenrolla efectivamente por síntesis, generando un conjunto de drivers que operan en paralelo, uno para cada salida.BenAdamson
usuario_1818839
miedo_jeff
send_s <= (others => '0'); send_s(line_select_s) <= prbs_i(0);
no funcionaría.miedo_jeff
usuario_1818839
miedo_jeff
usuario_1818839
natural range 0 to 4
(o el rango del puerto de salida) por lo que tales errores no fueron posibles. Pero me gusta ver ambos enfoques en la respuesta, nunca se sabe cuándo puede ser necesario el ciclo.