in

Verilog: búfer variable con entrada/salida diferente

Tengo algunos problemas con un búfer que recibe una entrada de 192 bits y se lee 72 bits. Suponer que escribir_es y leer_es son asíncronos, pero el búfer no se llena ni se vacía.

He probado el módulo y parece que está funcionando según lo diseñado, pero hay un punto en el que cuando ambos escribir_es y leer_es son ciertas, deja de funcionar. Creo que está relacionado con el contador, pero no puedo entenderlo. ¿Ves algo que me perdí?

Agrego el módulo Verilog como referencia:

module variable_buffer #(parameter WORD_SIZE_IN = 192, WORD_SIZE_OUT = 72)(
    input wire clk250, rst, write_en, read_en,
    input wire [0:WORD_SIZE_IN-1] data_in,
    output reg [0:WORD_SIZE_OUT-1] data_out_buffer,
    output reg [0:8] data_count,
    output reg full, empty, error);

//--------  internal variable declaration   -------------------------------------------
    reg [0:WORD_SIZE_IN*2-1] buffer_reg; // 368 = WORD_SIZE_IN*2-1
    reg [0:8] counter, aux_counter;
    reg flag_buffer_full, flag_buffer_empty, aux_flag_buffer_full, aux_flag_buffer_empty;
    reg count_add, count_sub;
//-------------------------------------------------------------------------------------

//--------  update states   -----------------------------------------------------------
    always @(posedge clk250) begin: update_registers
        if(rst == 1'b0) begin
            counter             <= 0;
            flag_buffer_full    <= 1'b0;
            flag_buffer_empty   <= 1'b1;
        end
        else begin
            counter             <= aux_counter;
            flag_buffer_full    <= aux_flag_buffer_full;
            flag_buffer_empty   <= aux_flag_buffer_empty;
        end
    end
//-------------------------------------------------------------------------------------

//--------  control full/empty flags and counter --------------------------------------
    always @(write_en, read_en, counter, flag_buffer_empty, flag_buffer_full) begin: flag_control
        aux_flag_buffer_full    = flag_buffer_full;
        aux_flag_buffer_empty   = flag_buffer_empty;
        count_sub   = 1'b0;
        count_add   = 1'b0;
        // write attempt
        if(write_en && !read_en && !flag_buffer_full) begin
            if(counter + WORD_SIZE_IN <= WORD_SIZE_IN*2) begin
                count_add = 1'b1;
                aux_flag_buffer_empty = 1'b0;
                if(counter + WORD_SIZE_IN == WORD_SIZE_IN*2) aux_flag_buffer_full = 1'b1;
            end else aux_flag_buffer_full = 1'b1;
        end
        
        // read attempt
        if(read_en && !write_en && !flag_buffer_empty) begin
            if(counter + WORD_SIZE_OUT > WORD_SIZE_OUT) begin
                count_sub               = 1'b1;
                aux_flag_buffer_full    = 1'b0;            
            end else count_sub = 1'b0;
                
            if(counter - WORD_SIZE_OUT < WORD_SIZE_OUT) begin
                aux_flag_buffer_empty   = 1'b1;
            end
        end

        // read & write attempt
        if(read_en && write_en) begin

            if(counter + WORD_SIZE_IN <= WORD_SIZE_IN*2) begin
                count_add = 1'b1;
                aux_flag_buffer_empty = 1'b0;
                if(counter + WORD_SIZE_IN == WORD_SIZE_IN*2) aux_flag_buffer_full = 1'b1;
            end else aux_flag_buffer_full = 1'b1;

            if(counter + WORD_SIZE_OUT > WORD_SIZE_OUT) begin
                count_sub               = 1'b1;
                aux_flag_buffer_full    = 1'b0;            
            end else count_sub = 1'b0;
                
            if(counter - WORD_SIZE_OUT < WORD_SIZE_OUT) begin
                aux_flag_buffer_empty   = 1'b1;
            end
        end
    end
//-------------------------------------------------------------------------------------

//--------  data operations    --------------------------------------------------------
    always @(posedge clk250) begin: data_update
        if(rst == 1'b0) begin
            buffer_reg          <= 0;
            data_out_buffer     <= 0;
            error               <= 1'b0;
        end
        if(write_en && !flag_buffer_full) begin // writing to buffer and is not full
            buffer_reg[counter +: WORD_SIZE_IN] <= data_in;
            error <= 1'b0;
        end
        else if (write_en && flag_buffer_full) error <= 1'b1; // error when trying to write in full buffer
        
        if(read_en && !flag_buffer_empty) begin // reading from non-empty buffer
            data_out_buffer <= buffer_reg[0:WORD_SIZE_OUT-1];
            buffer_reg      <= buffer_reg << WORD_SIZE_OUT;
            error           <= 1'b0;
        end
        else if(read_en && flag_buffer_empty) error <= 1'b1; // error when reading from empty buffer
        
        if(read_en && write_en && !flag_buffer_empty && !flag_buffer_full) begin
            data_out_buffer <= buffer_reg[0:WORD_SIZE_OUT-1];
            buffer_reg      <= buffer_reg << WORD_SIZE_OUT;
            buffer_reg[counter +: WORD_SIZE_IN] <= data_in;
            error           <= 1'b0;
        end

    end  
//-------------------------------------------------------------------------------------

//--------  combinational counter    --------------------------------------------------
    always @(count_sub, count_add, counter) begin: counter_operations
        begin: combi_counter
            case({count_sub, count_add})
                2'b01   : aux_counter = counter + WORD_SIZE_IN;
                2'b10   : aux_counter = counter - WORD_SIZE_OUT;
                default : aux_counter = counter;
            endcase
        end
    end
//-------------------------------------------------------------------------------------

//--------  connection internal registries to ports -----------------------------------
    always @(counter, flag_buffer_full, flag_buffer_empty) begin: inner_2_port_connections
        data_count  = counter;
        full        = flag_buffer_full;
        empty       = flag_buffer_empty;
    end
//-------------------------------------------------------------------------------------

endmodule

0

¿Te ayudó la respuesta?

Subscribirse
Notificar por
guest
0 Comentarios
Inline Feedbacks
Ver todas las Respuestas

No se puede eliminar el documento de la cola de impresión, solo se muestra «eliminando»

Almacenamiento necesario en un GeoServer de aprendizaje de VM