1

I have written this code in verilog and I have a problem with my code! What I want to do is to give as input the numbers 0 - 127 , so they can be written in mem and then to read them and see the output. I have set the clock to change every 5 from 0 to 1, which is happening, according to the results. But the numbers are being witten more than once in the memory. How can I fix this, in order the numbers will be written only once ? Could it be a timing-clocking problem ?

At the beginning the output data is 0, because I need to write the data first and then read them.

Also, I would like to know what I need to change so that when the last position of the memory is filled with the number 127, my program will understand that no other position of the memory is left empty!! I am running the code in EDA Playground.

module process_data( input wire [63:0] DATA_IN , //input data input QUE_Mode, //fifo or filo //input wire [6:0] AdrR , //pointers for read, write //input wire [6:0] AdrW, input R_W , input Cen, input clk, input reset, output reg [63:0]Reg_Data_Out, //output data output reg Que_Full, //state of the queue output reg Que_Last, output reg Que_Empty); integer i; reg [63:0] Memory [0:127]; //array reg [6:0] AdrW; reg [6:0] AdrR; initial begin //initialization Que_Full= 1'b0; //when Que_Full = 1'b0, the queue is not full Que_Last = 1'b0; //when Que_Last = 1'b0, this is not the last item of the list that can be added to Que_Empty = 1'b0; //when Que_Empty = 1'b0, the queue is empty. AdrR=7'b0000_000; AdrW=7'b0000_000; i=0; repeat (128) //initialization of memory begin Memory[i]=64'd1; //64 bits/ position , 127 positions i=i+1; end end always @* begin $display("AdrR=%d",AdrR); $display("AdrW=%d",AdrW); end always @(negedge(clk)) begin if(Cen == 1'b1) begin // cen = chip enabled , when 1=> chip is enabled => circuit works case (R_W) 1'b1: begin if(Que_Empty == 1'b1 )begin //check if queue not empty // Return the value from the FIFO foun at the read address Reg_Data_Out <= Memory[AdrR]; // (read) out put memory context AdrR<=AdrR+7'b0000_001; //assign AdrR [6:0] <= AdrR [6:0] +7'b0000_001; end end 1'b0: begin if( Que_Full == 1'b0 )begin //check if queue not full if(AdrW >= 7'b0000_000) begin Memory[AdrW] <= DATA_IN ; // write input to memory , On any write -> update the memory AdrW <= AdrW+7'b0000_001; //non blocking statements to avoid race conditions Que_Empty = 1'b1; //when Que_Empty = 1'b1, the queue is NOT empty if(AdrW==7'b1111_111)begin //AdrW <= 7'b0000_000; Que_Full= 1'b1; //when Que_Full = 1'b1, the queue IS full Que_Last = 1'b1; //when Que_Last = 1'b0, this IS the last item of the list that can be added to end end end end default: Reg_Data_Out = 64'bxxxxxxxx; endcase end end endmodule module clock(output reg clk); initial clk=1'b0; always #5 clk=~clk; endmodule module TOP(); parameter ENDTIME=40000; reg [63:0] inputdata1; // is an 63-bit "register", or variable wire [6:0] AddressR,AddressW; reg cen, R_W, reset; //clk=1'b0 , reg QUE_Mode; wire [63:0] Data_Out; integer count; integer i; wire Que_Full, Que_Last, Que_Empty; wire clk; //call module for data I/O process_data process_data( inputdata1, QUE_Mode, //AddressR, //AddressW, R_W , cen, clk, reset, Data_Out, Que_Full, Que_Last, Que_Empty); //reset, Que_Full, Que_Last, Que_Empty do not do anything yet clock MyClock(clk); initial begin $dumpfile("ALU.vcd"); $dumpvars(0); $display("\t\t\t\t\t\t\t\t\tSIMULATION RESULT "); $display("\t\ttime\tclk\t\t\tinputdata1\t\tData_Out\tQUE_Mode\t\tAddressR\t\tAddressW\t\tQue_Full\t\Que_Last\t\Que_Empty"); $monitor($time, "\t%d\t%d\t%d\t%d",clk,inputdata1,Data_Out,QUE_Mode,AddressR,AddressW,Que_Full,Que_Last,Que_Empty); cen=1'b1; //chip enabled count = 0; R_W = 1'b0; //write QUE_Mode = 1'b0; // QUE_Mode = 1'b0 => FIFO MODE i=0; //input for (i = 0; i < 128; i = i + 1) begin //input R_W=1'b0; //write inputdata1 = i; #20; end #10 for (i = 0; i < 128; i = i + 1) begin //output #20; R_W=1'b1; //read => output #20; end $display("-------------- THE SIMULATION FINISHED ------------"); $finish; end endmodule 

RESULTS:

 SIMULATION RESULT time clk inputdata1 Data_Out QUE_Mode AddressR AddressW Que_Full Que_Last Que_Empty AdrR= 0 AdrW= 0 AdrR= 0 AdrW= 1 0 0 0 x 0 z z001 5 1 0 x 0 z z001 AdrR= 0 AdrW= 2 10 0 0 x 0 z z001 15 1 0 x 0 z z001 AdrR= 0 AdrW= 3 20 0 1 x 0 z z001 25 1 1 x 0 z z001 AdrR= 0 AdrW= 4 30 0 1 x 0 z z001 35 1 1 x 0 z z001 AdrR= 0 AdrW= 5 40 0 2 x 0 z z001 45 1 2 x 0 z z001 AdrR= 0 AdrW= 6 50 0 2 x 0 z z001 55 1 2 x 0 z z001 AdrR= 0 AdrW= 7 60 0 3 x 0 z z001 65 1 3 x 0 z z001 AdrR= 0 AdrW= 8 70 0 3 x 0 z z001 75 1 3 x 0 z z001 AdrR= 0 AdrW= 9 80 0 4 x 0 z z001 85 1 4 x 0 z z001 AdrR= 0 AdrW= 10 90 0 4 x 0 z z001 95 1 4 x 0 z z001 AdrR= 0 AdrW= 11 100 0 5 x 0 z z001 105 1 5 x 0 z z001 AdrR= 0 AdrW= 12 110 0 5 x 0 z z001 115 1 5 x 0 z z001 AdrR= 0 AdrW= 13 120 0 6 x 0 z z001 125 1 6 x 0 z z001 AdrR= 0 AdrW= 14 130 0 6 x 0 z z001 135 1 6 x 0 z z001 ...................... AdrR=121 AdrW= 0 7630 0 127 60 0 z z111 7635 1 127 60 0 z z111 AdrR=122 AdrW= 0 7640 0 127 60 0 z z111 7645 1 127 60 0 z z111 AdrR=123 AdrW= 0 7650 0 127 61 0 z z111 7655 1 127 61 0 z z111 AdrR=124 AdrW= 0 7660 0 127 61 0 z z111 7665 1 127 61 0 z z111 AdrR=125 AdrW= 0 7670 0 127 62 0 z z111 7675 1 127 62 0 z z111 AdrR=126 AdrW= 0 7680 0 127 62 0 z z111 7685 1 127 62 0 z z111 -------------- THE SIMULATION FINISHED ------------ AdrR=127 7690 0 127 63 0 z z111 Done 
1
  • Seeing the first lines of the results, where addrw=1 and addrw=2(write pointer), the input is 0 0 and then 0 0 !!!! The number : 0 is being given 4 times as input, Commented Jun 1, 2020 at 19:25

1 Answer 1

1

You need to change your input data twice as quickly. Change #20 to #10:

 //input for (i = 0; i < 128; i = i + 1) begin //input R_W=1'b0; //write inputdata1 = i; // #20; #10; end 

This will write 0 to address 0, 1 to address 1, ... 127 to address 127.


The 1st write is to address 0 at time=0. However, there is a race condition between the initial and always blocks which could result in different behavior on different simulators.


The log file shows output on every edge of clk, both posedge and negedge, because you have clk in the $monitor statement. But, the data is only changing once per clock period (as desired).

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.