Prioridad MUX: seleccione una de las opciones según el valor anterior

0

Tengo varios trabajadores que necesitan acceder al bus único (canal de memoria). Varios de ellos pueden estar listos al mismo tiempo y me gustaría que se alternen con los escritores que tengan prioridad.

Tengo algunos pseudocódigo con dos escritores y dos lectores para mostrar, pero no es una buena solución y lo necesito para escalar con un número arbitrario de trabajadores (los escritores y los lectores vienen en pares). También me preocupa la utilización de recursos.

if curr_worker = wr0 then
    curr_worker <= wr1 when w_rdy[1] = '1' else
                   wr0 when w_rdy[0] = '1' else
                   rd0 when r_rdy[0] = '1' else
                   rd1 when r_rdy[1] = '1' else
                   dummy;
else if curr_worker = rd0 then
    curr_worker <= wr0 when w_rdy[0] = '1' else
                   wr1 when w_rdy[1] = '1' else
                   rd1 when r_rdy[1] = '1' else
                   rd0 when r_rdy[0] = '1' else
                   dummy;
else
    curr_worker <= wr0 when w_rdy[0] = '1' else
                   wr1 when w_rdy[1] = '1' else
                   rd0 when r_rdy[0] = '1' else
                   rd1 when r_rdy[1] = '1' else
                   dummy;
end if;

Y solo para estar seguros, la instrucción when-else asignará la primera opción cuando la condición sea verdadera, incluso si la siguiente condición también es verdadera, ¿correcto?

    
pregunta David Novák

2 respuestas

1

Suena como si quisieras un árbitro de round robin. Ciertamente existen, y con un poco de codificación cuidadosa es posible escribir una parametrizable. Por ejemplo, enlace es un árbitro que escribí hace un tiempo que puede operar en Prioridad estricta o en modo round robin, con el número de entradas seleccionables en el momento de la síntesis con un parámetro. Este módulo utiliza este codificador de prioridad parametrizable internamente: enlace .

    
respondido por el alex.forencich
1

Lo que quieres es servicio de round robin con prioridad de escritura. Para el round robin tienes que recordar lo que pasó antes. Su código se convertirá en algo así: (este es un pseudo código para tres canales)

if there_is_a_write then
   case previous_write
      when 0 => 
         if write1 then 
            select = 1 else
         if write2 then 
            select = 2 else
         select = 0;
      when 1 => 
         if write2 then 
            select = 2 else
         if write0 then 
            select = 0 else
         select = 1;
      when 2 => 
         if write0 then 
            select = 0 else
         if write1 then 
            select = 1 else
         select = 2;
   end case
else
if there_is_a_read then
   case previous_read
      when 0 => 
         if read1 then 
            select = 1 else
         if read2 then 
            select = 2 else
         select = 0;
      when 1 => 
         if read2 then 
            select = 2 else
         if read0 then 
            select = 0 else
         select = 1;
      when 2 => 
         if read0 then 
            select = 0 else
         if read1 then 
            select = 1 else
         select = 2;
  end case

Tienes que agregar código para recordar la lectura y escritura anteriores.

Puede realizar cambios como tener solo un 'anterior' sin distinguir entre lectura o escritura.

    
respondido por el Oldfart

Lea otras preguntas en las etiquetas