特定种类的计数器的Verilog代码(问题)

时间:2014-12-21 14:29:04

标签: memory verilog

下午好人们,我试图在Verilog中编码一个结构,而不是可以存储多达64个不同的8位数字(64X8),只允许存储大于125且低于或等于250的数字。当它是写(或不写),它可以显示最大当前存储值(VAL_MAX)以及它的位置(POS_MAX)。当不写(EN_WR == 0)时,我只需在POS_RD中输入我想要的位置,以便查看存储在那里的数字,并且当存储器已满(NR_ST = 64)时,它会用新的替换最旧存储的数字。一个接一个。我目前有代码,但有一些问题:

1st - 当内存已满并且例如。我在第二个位置有250,输出将是 VAL_MAX = 250;的Pos_max = 1。当一堆新数字出现时,该最大值应该被第二个最高存储值替换,并且必须显示它的位置,但是内存没有显示新的最大值。

第二 - 当我想看到存储在第一个位置(POS_RD = 0)的数字时,输出VAL_RD(用于读取存储的数字)是“X”而不是存储的数字,我不知道是否正在拯救与否。

代码是:

module Bloco(VAL_SENSOR, EN_WR, POS_RD, NR_ST, VAL_MAX, POS_MAX, VAL_RD, segundo, clk);

parameter MEM_SIZE = 64;
parameter MEM_WIDTH = 8;
parameter ADDR_SIZE = 5;

input[MEM_WIDTH - 1:0] VAL_SENSOR;
input[5:0] POS_RD;
input EN_WR,segundo,clk; 

output[6:0] NR_ST;  
output[MEM_WIDTH - 1:0] VAL_MAX; 
output[ADDR_SIZE    :0]POS_MAX; 
output[MEM_WIDTH - 1:0]VAL_RD;

reg[MEM_WIDTH - 1:0] ram[MEM_SIZE - 1:0]; // C , L
reg[MEM_WIDTH - 1:0] VAL_RD;

reg[MEM_WIDTH - 1:0] val_max = 0;       //necessita de variavel so por causa do valor inicial
reg[ADDR_SIZE    :0] POS_MAX = 0;
reg[ADDR_SIZE    :0] POS_MAX2 = 0;
reg[ADDR_SIZE + 1:0] NR_ST_COUNTER = 0; //addr_size + 1 because it needs to count from zero to the number of values
reg[ADDR_SIZE    :0] POS_POINTER = 0;

assign VAL_MAX = val_max;
assign NR_ST = NR_ST_COUNTER;

always @ (posedge clk) 
begin
    if(EN_WR) //Caso esteja habilitado o sistema de armazenamento
    begin
        if(segundo)
        begin
            if(VAL_SENSOR > 125 && VAL_SENSOR <= 250) //Se for um numero abaixo de 250 unid. luminosas e acima de 125
            begin   //Escrita
                if(POS_POINTER == POS_MAX)
                    POS_MAX <= POS_MAX2;
                else
                    ram[POS_POINTER] <= VAL_SENSOR;

                if(NR_ST_COUNTER < 64)      //atualizar Contador de Valores guardados
                    NR_ST_COUNTER = NR_ST_COUNTER + 1;

                if(VAL_SENSOR > val_max)    //atualizar MAX
                begin
                    POS_MAX <= POS_POINTER;
                    val_max <= VAL_SENSOR;
                end
                else                        //ver se encaixa no segundo maior POS_MAX2
                begin
                    if(VAL_SENSOR > ram[POS_MAX2])      //nao precisa guardar o valor

                        POS_MAX2 <= POS_POINTER;

                end
                POS_POINTER <= POS_POINTER + 1;
            end
        end
    end
    else
        VAL_RD <= ram[POS_RD];
    end

endmodule 

注意=输入“segundo”与EN_WR类似,但它仅在10个时钟周期后使用(它将链接到计数器)。 谢谢。

1 个答案:

答案 0 :(得分:0)

回答你的问题:

1)当你的当前最大值被覆盖时,你可能没有看到内存中第二个最高值的原因出现在VAL_MAX是因为你永远不会改变val_max寄存器来包含值{{ 1}},即第二高的值。但是,由于您没有有序的数据结构并且不存储任何超过第二个最高值(并且不搜索内存中的第二个最高值),因此当前最高值时,您无法可靠地继续查找下一个最高值删除/覆盖。如果您需要始终在ram[POS_MAX2]输出的内存中保持当前最高值,则可能需要重新考虑如何执行此操作。

2)第一次写入存储器时,位置0没有被写入;因此,您将获得内存的默认值,即VAL_MAX。这样:

'x

在上面的行中,如果当前位置不等于当前最高值的位置,则只将值放入内存中。第一次写入(即位置0)时,if(POS_POINTER == POS_MAX) POS_MAX <= POS_MAX2; else ram[POS_POINTER] <= VAL_SENSOR; POS_POINTER的初始值为0,因此相等。因此,POS_MAX永远不会更新,因为只有在ram[0]POS_POINTER不相等时才执行此更新(在这种情况下,它们相同)。如果您第二次写入位置0,则可能会写入POS_MAX的值可能已更改。另请注意,有时您更新写指针POS_MAX即使您没有在那里写,如上例所示(即使POS_POINTER没有写入,您仍然会更新ram[0]为1)。

如#1中所述,根据您的要求,您可能没有合适的结构来满足它们。如果始终需要在POS_PONTER的内存输出中具有最高值并且始终具有弹出的旧值,则可能需要使这些操作中的旧值进行搜索,或者存储和更新所有需要的元数据。