Sign In

Don't have a Xilinx account yet?

  • Choose to receive important news and product information
  • Gain access to special content
  • Personalize your web experience on Xilinx.com

Create Account

Username

Password

Forgot your password?
XClose Panel
Xilinx Home
Reply
Regular Visitor
anikau31
Posts: 19
Registered: ‎01-13-2012
0

Re: unknown values in sim

Yes sir. My apologies. They do not show any unknown values.

 

I wrongly stated my error. 

Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

Re: unknown values in sim

[ Edited ]

Yes sir. My apologies. They do not show any unknown values. I wrongly stated my error.

 

It was your turn :)  This makes the two of us even (see posts #13 and #15 in this thread).

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Regular Visitor
anikau31
Posts: 19
Registered: ‎01-13-2012
0

Re: unknown values in sim

Perhaps this is my last glitch in the mltiported memory design.

 

In the testbench screen shot, please focus on the following signals: clock, write_en, addr_3 and read_data3.

 

As you can observe, when I am giving a address input at addr_3 I get the corresponding updated value stored in that address displayed through read_data3. That is observed through the first cyle of write_en

 

However, on carefully observing the next cycle of write_en, for one time cycle a different value is shown and then the correct value is displayed on the next clock cycle. What is the reason for this glitch?

 

Thanks

error2.bmp
Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

Re: unknown values in sim

[ Edited ]

However, on carefully observing the next cycle of write_en, for one time cycle a different value is shown and then the correct value is displayed on the next clock cycle. What is the reason for this glitch?

 

Suggest you re-simulate, with all the signals in the path to read_data_3 included in the simulation.  The register read_data_3 is the output of a clocked mux_data_2to1 block, but the code for this block has not been posted.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Regular Visitor
anikau31
Posts: 19
Registered: ‎01-13-2012
0

Re: unknown values in sim

I have attached the creenshot of all the signals leading to the read_data3. 

 

read_data_3 is the output from reading address input address_3. This output is the final output port of the multi-ported design.

 

addr_3 is the input address port of the multiported design.

 

Now, read_data_3 is the output obtained from the MUX based on the following working. There are two inputs to the MUX. One input is the data stored at address X from Bank 1 and the other input is the data stored at same address X from Bank2. The control signal determines which bank has the recently written value for that address. The signals for the MUX are as follows: selector, data_0 (data from Bank 0), data_1 (data from bank 1) and output_data.

 

The input to the MUX us from the output of Bank 1 and Bank 0 for the corresponding read_addr input. In this case for addr_3, the inputs to the MUX are the outputs read_data_0_3 which is output from bank 0 and read_data_1_3 which is output from bank 1. 

 

As you can observe data from read_data_0_3 will be sonsidered because the selector signal indicates that Bank 0 is the right bank. Hence I have also included signals from Bank 0. The signals from Bank 0 are clock, we_0, we_1, addr_0, addr_1, data_0, data_1, read_data0 and read_data1.

 

Also, at 600ns the value which is partially covered is the binary equivalent of 390. The testbench and the coding for MUX is given below.

 

my_multipumped_memory uut (
		.clock(clock), 
		.write_en(write_en), 
		.write_data_0(write_data_0), 
		.write_data_1(write_data_1), 
		.write_data_2(write_data_2), 
		.write_data_3(write_data_3), 
		.write_addr2(write_addr2), 
		.write_addr3(write_addr3), 
		.addr_0(addr_0), 
		.addr_1(addr_1), 
		.addr_2(addr_2), 
		.addr_3(addr_3), 
		.addr_4(addr_4), 
		.addr_5(addr_5), 
		.addr_6(addr_6), 
		.addr_7(addr_7), 
		.read_data_0(read_data_0), 
		.read_data_1(read_data_1), 
		.read_data_2(read_data_2), 
		.read_data_3(read_data_3), 
		.read_data_4(read_data_4), 
		.read_data_5(read_data_5), 
		.read_data_6(read_data_6), 
		.read_data_7(read_data_7)
	);

	initial
	clock = 1'b1;
	
	always
	#50 clock = ~clock;
	
	initial
	#10000 $finish;
	
	initial
	write_en = 1'b1;
	
	always
	#200 write_en = ~write_en;
	
	initial
	#10000 $finish;
	
	initial
	begin
	#30 write_data_2 = 32'd86;  write_addr2 = 8'b11001100;
		 write_data_3 = 32'd144; write_addr3 = 8'b10010110;
		 write_data_0 = 32'd118; addr_0 = 8'b11011010;
		 write_data_1 = 32'd390; addr_1 = 8'b00110101;
		 
		  #180 
				
				addr_3 = 8'b11011010;
				
		
				
		
		 end
		 
		 
      
endmodule

 Below is the code for MUX

 

module MUX_data_2to1(selector, data_0, data_1, output_data);

input selector;

input [31:0] data_0;
input [31:0] data_1;

output reg [31:0] output_data;

always @(*) begin

    case(selector)

        1'b0: begin
			output_data <= data_0;
        end

        1'b1: begin
			output_data <= data_1;
        end


    endcase
end

endmodule

 Thanks

main error.bmp
Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

not ready for review

I sat down to try to chase down your problem, and I came across a roadblock.

 

Your code calls module MUX_data_2to1, and clock is on the module port list (see post #19 in this thread).

Then you post the code for module MUX_data_2to1, and this module has no clock port (see post #25 in this thread).

 

It seems that I am tracing through pieces of code from two different sets (revisions) of your code.  Please let us know when your code settles down.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Regular Visitor
anikau31
Posts: 19
Registered: ‎01-13-2012
0

Re: not ready for review

Sir,

 

The clock is not part of the MUX. The code that I have posted recent is the final code for the MUX.

 

Thank you for your help and guidance.

Regular Visitor
anikau31
Posts: 19
Registered: ‎01-13-2012
0

Re: not ready for review

Also I have another small doubt.

 

Suppose I have the following declaration for a memory register

 

reg [31:0] ram [0:255].

 

The above implies a 32 bit data width RAM of 256 memory locations. Assume that read_Addr is a signal that accesses the RAM. If I want to change the 30th bit of the data stored at read_Addr say from one to zero, how do I do it?

 

Thank you once again for your valuable help and guidance. 

Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

Re: not ready for review

[ Edited ]

The clock is not part of the MUX. The code that I have posted recent is the final code for the MUX.

 

The rest of your code includes additional changes, so please post your entire code from a single version along with matching simulation results.

 

reg [31:0] ram [0:255].

 

The above implies a 32 bit data width RAM of 256 memory locations. Assume that read_Addr is a signal that accesses the RAM. If I want to change the 30th bit of the data stored at read_Addr say from one to zero, how do I do it?

 

  • Select this bit as follows:  ram[read_Addr][30].
  • The MSB of the addressed memory word is ram[read_Addr][31]
  • The LSB of the addressed memory word is ram[read_Addr][0]

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Regular Visitor
anikau31
Posts: 19
Registered: ‎01-13-2012
0

Re: not ready for review

The following is the code to the design.

 

The top level module of the multiported design

module my_multipumped_memory(clock, write_en, write_data_0, write_data_1, write_data_2, write_data_3, 
write_addr2, write_addr3, addr_0, addr_1, addr_2, addr_3, addr_4, addr_5, addr_6, addr_7, read_data_0, read_data_1, read_data_2,
read_data_3, read_data_4, read_data_5, read_data_6, read_data_7);
 
input clock;
input write_en;

input [7:0] addr_0;
input [7:0] addr_1;
input [7:0] addr_2;
input [7:0] addr_3;
input [7:0] addr_4;
input [7:0] addr_5;
input [7:0] addr_6;
input [7:0] addr_7;
input [7:0] write_addr2;
input [7:0] write_addr3;

input [31:0] write_data_0;
input [31:0] write_data_1;
input [31:0] write_data_2;
input [31:0] write_data_3;

output  [31:0] read_data_0;
output  [31:0] read_data_1;
output  [31:0] read_data_2;
output  [31:0] read_data_3;
output  [31:0] read_data_4;
output  [31:0] read_data_5;
output  [31:0] read_data_6;
output  [31:0] read_data_7; 

wire [31:0] read_data_0_0;
wire [31:0] read_data_0_1;
wire [31:0] read_data_0_2;
wire [31:0] read_data_0_3;
wire [31:0] read_data_0_4;
wire [31:0] read_data_0_5;
wire [31:0] read_data_0_6;
wire [31:0] read_data_0_7;

wire [31:0] read_data_1_0;
wire [31:0] read_data_1_1;
wire [31:0] read_data_1_2;
wire [31:0] read_data_1_3;
wire [31:0] read_data_1_4;
wire [31:0] read_data_1_5;
wire [31:0] read_data_1_6;
wire [31:0] read_data_1_7;

reg [7:0] muxeaddr_2;
reg [7:0] muxeaddr_3;

wire read_0;
wire read_1;
wire read_2;
wire read_3;
wire read_4;
wire read_5;
wire read_6;
wire read_7;

always @(*) begin

if(write_en == 1'b1) begin
muxeaddr_2 <= write_addr2;
muxeaddr_3 <= write_addr3;
end

else begin
muxeaddr_2 <= addr_0;
muxeaddr_3 <= addr_1;
end

end

lvt_4w8r lvt(
.clock(clock),
.enable(write_en),
.write_address_0(addr_0),
.write_address_1(addr_1),
.write_address_2(muxeaddr_2),
.write_address_3(muxeaddr_3),
.read_addr_0(addr_0),
.read_addr_1(addr_1),
.read_addr_2(addr_2),
.read_addr_3(addr_3),
.read_addr_4(addr_4),
.read_addr_5(addr_5),
.read_addr_6(addr_6),
.read_addr_7(addr_7),
.read_addr_tag_0(read_0),
.read_addr_tag_1(read_1),
.read_addr_tag_2(read_2),
.read_addr_tag_3(read_3),
.read_addr_tag_4(read_4),
.read_addr_tag_5(read_5),
.read_addr_tag_6(read_6),
.read_addr_tag_7(read_7)
);


memory_2w8r mem0 (
.clock(clock),
.write_en(write_en),
.write_data_0(write_data_0),
.write_data_1(write_data_1),
.addr_0(addr_0),
.addr_1(addr_1),
.addr_2(addr_2),
.addr_3(addr_3),
.addr_4(addr_4),
.addr_5(addr_5),
.addr_6(addr_6),
.addr_7(addr_7),
.read_data_0(read_data_0_0),
.read_data_1(read_data_0_1),
.read_data_2(read_data_0_2),
.read_data_3(read_data_0_3),
.read_data_4(read_data_0_4),
.read_data_5(read_data_0_5),
.read_data_6(read_data_0_6),
.read_data_7(read_data_0_7)
);

memory_2w8r mem1 (
.clock(clock),
.write_en(write_en),
.write_data_0(write_data_2),
.write_data_1(write_data_3),
.addr_0(muxeaddr_2),
.addr_1(muxeaddr_3),
.addr_2(addr_2),
.addr_3(addr_3),
.addr_4(addr_4),
.addr_5(addr_5),
.addr_6(addr_6),
.addr_7(addr_7),
.read_data_0(read_data_1_0),
.read_data_1(read_data_1_1),
.read_data_2(read_data_1_2),
.read_data_3(read_data_1_3),
.read_data_4(read_data_1_4),
.read_data_5(read_data_1_5),
.read_data_6(read_data_1_6),
.read_data_7(read_data_1_7)
);

MUX_data_2to1 m0(

.selector(read_0),
.data_0(read_data_0_0),
.data_1(read_data_1_0),
.output_data(read_data_0)
);


MUX_data_2to1 m1(

.selector(read_1),
.data_0(read_data_0_1),
.data_1(read_data_1_1),
.output_data(read_data_1)
);


MUX_data_2to1 m2(

.selector(read_2),
.data_0(read_data_0_2),
.data_1(read_data_1_2),
.output_data(read_data_2)
);


MUX_data_2to1 m3(

.selector(read_3),
.data_0(read_data_0_3),
.data_1(read_data_1_3),
.output_data(read_data_3)
);


MUX_data_2to1 m4(

.selector(read_4),
.data_0(read_data_0_4),
.data_1(read_data_1_4),
.output_data(read_data_4)
);


MUX_data_2to1 m5(

.selector(read_5),
.data_0(read_data_0_5),
.data_1(read_data_1_5),
.output_data(read_data_5)
);


MUX_data_2to1 m6(

.selector(read_6),
.data_0(read_data_0_6),
.data_1(read_data_1_6),
.output_data(read_data_6)
);


MUX_data_2to1 m7(

.selector(read_7),
.data_0(read_data_0_7),
.data_1(read_data_1_7),
.output_data(read_data_7)
);



endmodule

  The Memory controller (Live Vaue Table) is below:

module lvt_4w8r (clock, enable, write_address_0, write_address_1, write_address_2, write_address_3, read_addr_0, read_addr_1, read_addr_2, read_addr_3, read_addr_4,read_addr_5, read_addr_6, read_addr_7,read_addr_tag_0, read_addr_tag_1, read_addr_tag_2, read_addr_tag_3, read_addr_tag_4, read_addr_tag_5, 
read_addr_tag_6, read_addr_tag_7);

input clock;
input enable;

input [7:0] write_address_0;
input [7:0] write_address_1;
input [7:0] write_address_2;
input [7:0] write_address_3;
input [7:0] read_addr_0;
input [7:0] read_addr_1;
input [7:0] read_addr_2;
input [7:0] read_addr_3;
input [7:0] read_addr_4;
input [7:0] read_addr_5;
input [7:0] read_addr_6;
input [7:0] read_addr_7;


output reg  read_addr_tag_0;
output reg  read_addr_tag_1;
output reg  read_addr_tag_2;
output reg  read_addr_tag_3;
output reg  read_addr_tag_4;
output reg  read_addr_tag_5;
output reg  read_addr_tag_6;
output reg  read_addr_tag_7;


reg [0:0] live_value_table [0:255];

always @(posedge clock) begin
if(enable) begin
    live_value_table[write_address_0] <= 1'b0;
    live_value_table[write_address_1] <= 1'b0;
    live_value_table[write_address_2] <= 1'b1;
    live_value_table[write_address_3] <= 1'b1;
end
else
begin
    read_addr_tag_0 <= live_value_table[read_addr_0];
    read_addr_tag_1 <= live_value_table[read_addr_1];
    read_addr_tag_2 <= live_value_table[read_addr_2];
    read_addr_tag_3 <= live_value_table[read_addr_3];
    read_addr_tag_4 <= live_value_table[read_addr_4];
    read_addr_tag_5 <= live_value_table[read_addr_5];  
    read_addr_tag_6 <= live_value_table[read_addr_6];
    read_addr_tag_7 <= live_value_table[read_addr_7];    
end

end
endmodule

 The Banked 2W/8R memory is given below:

module memory_2w8r(clock, write_en, addr_0, addr_1, addr_2, addr_3, addr_4, addr_5, addr_6, addr_7, write_data_0, write_data_1,
read_data_0, read_data_1, read_data_2, read_data_3, read_data_4, read_data_5, read_data_6, read_data_7);
    

input clock;
input write_en;

input [7:0] addr_0;
input [7:0] addr_1;
input [7:0] addr_2;
input [7:0] addr_3;
input [7:0] addr_4;
input [7:0] addr_5;
input [7:0] addr_6;
input [7:0] addr_7;


input [31:0] write_data_0;
input [31:0] write_data_1;

output [31:0] read_data_0;
output [31:0] read_data_1;
output [31:0] read_data_2;
output [31:0] read_data_3;
output [31:0] read_data_4;
output [31:0] read_data_5;
output [31:0] read_data_6;
output [31:0] read_data_7;

reg [7:0] muxed_addr_0;
reg [7:0] muxed_addr_1;
reg [7:0] muxed_addr_2;
reg [7:0] muxed_addr_3;
reg [7:0] muxed_addr_4;
reg [7:0] muxed_addr_5;


true_dual bank0 (
    .clock(clock),        
    .we_0(write_en),
    .we_1(write_en),
    .addr_0(addr_0),
    .addr_1(addr_1),
    .data_0(write_data_0),
    .data_1(write_data_1),
    .read_data0(read_data_0),
    .read_data1(read_data_1)
);

true_dual bank_1 (
     .clock(clock),        
    .we_0(write_en),
    .we_1(write_en),
    .addr_0(muxed_addr_0),
    .addr_1(muxed_addr_1),
    .data_0(write_data_0),
    .data_1(write_data_1),
    .read_data0(read_data_2),
    .read_data1(read_data_3)
);


true_dual bank_2 (
     .clock(clock),        
    .we_0(write_en),
    .we_1(write_en),
    .addr_0(muxed_addr_2),
    .addr_1(muxed_addr_3),
    .data_0(write_data_0),
    .data_1(write_data_1),
    .read_data0(read_data_4),
    .read_data1(read_data_5)
);


true_dual bank_3 (
     .clock(clock),        
    .we_0(write_en),
    .we_1(write_en),
    .addr_0(muxed_addr_4),
    .addr_1(muxed_addr_5),
    .data_0(write_data_0),
    .data_1(write_data_1),
    .read_data0(read_data_6),
    .read_data1(read_data_7)
);


always @(*) begin
    if(write_en == 1'b1) begin
        muxed_addr_0 <= addr_0;
        muxed_addr_1 <= addr_1;
		  muxed_addr_2 <= addr_0;
        muxed_addr_3 <= addr_1;
        muxed_addr_4 <= addr_0;
        muxed_addr_5 <= addr_1;
    end
    else begin
        muxed_addr_0 <= addr_2;
        muxed_addr_1 <= addr_3;
		  muxed_addr_2 <= addr_4;
	     muxed_addr_3 <= addr_5;
	     muxed_addr_4 <= addr_6;
	     muxed_addr_5 <= addr_7;
    end
end
endmodule

 The MUX 2 to 1 is given below

module MUX_data_2to1(selector, data_0, data_1, output_data);

input selector;

input [31:0] data_0;
input [31:0] data_1;

output reg [31:0] output_data;

always @(*) begin

    case(selector)

        1'b0: begin
			output_data <= data_0;
        end

        1'b1: begin
			output_data <= data_1;
        end


    endcase
end

endmodule

 The code for the single true dual BRAM is given below:

module true_dual(clock, we_0,we_1, data_0,data_1, addr_0,addr_1, read_data0, read_data1
    );

input clock;
input we_0;
input we_1;
input [7:0] addr_0;
input [7:0] addr_1;
input [31:0] data_0;
input [31:0] data_1;

output reg [31:0] read_data0;
output reg [31:0] read_data1;

reg [31:0] ram [0:255];

always @(posedge clock)
begin
   if (we_0) begin
       ram[addr_0] <= data_0;
   end
	else
   read_data0 <= ram[addr_0] ;
end
	
	
always @(posedge clock)
begin
   if (we_1) begin
       ram[addr_1] <= data_1;
   end
	else
   read_data1 <= ram[addr_1] ;
end
endmodule

The simulation screenshots are from this code.

 

 Thank you for your help.

Regards