Dual Port RAM: Different Bus Sizes?

D

deadsy

Guest
Hi:

I'm trying to define a dual port ram device with a 16kx16bit bus and a
32Kx8bit bus referring to the same memory.
The following gets the job done- but it uses a mux to select 8 of 16 for the
8 bit data bus.
I'm using a Xilinx part and I understand the ram blocks can be setup with
different bus aspect ratios.
Is there a way to convince the synthesiser to do this in plain old verilog,
without resorting to direct instantiation of the Xilinx ram block primitive?

I'm a newbie to verilog- so I hope this isn't a dumb question.

Thanks,
Jason H.

module system_ram
(
input clk,
input we,
input [13:0] adr,
input [15:0] di,
output reg [15:0] do,
input vclk,
input [14:0] vadr,
output [7:0] vdata
);

// 16384 x 16 bits = 32K

reg [15:0] mem[0:16383];

always @( posedge clk ) begin
if ( we != 0 )
mem[adr] <= di;
else
do <= mem[adr];
end

reg [15:0] q;

always @( posedge vclk ) begin
q <= mem[vadr>>1];
end

assign vdata = (vadr&1) ? q[7:0] : q[15:8];

endmodule
 
Hi Jason,

I think a synthesizer would need to be pretty smart to infer
a block ram with different port sizes. Also note that the code
you have below does not describe this. In the block ram
without an output mux, the data on the output would depend
on the address of the previous clock cycle. Your mux
is combinatorial and uses the LSB of the address on this clock
cycle. If a synthesis tool could infer a block RAM with two
different port sizes, you'd need to fix this.

Good Luck,
Gabor

deadsy wrote:
Hi:

I'm trying to define a dual port ram device with a 16kx16bit bus and a
32Kx8bit bus referring to the same memory.
The following gets the job done- but it uses a mux to select 8 of 16 for the
8 bit data bus.
I'm using a Xilinx part and I understand the ram blocks can be setup with
different bus aspect ratios.
Is there a way to convince the synthesiser to do this in plain old verilog,
without resorting to direct instantiation of the Xilinx ram block primitive?

I'm a newbie to verilog- so I hope this isn't a dumb question.

Thanks,
Jason H.

module system_ram
(
input clk,
input we,
input [13:0] adr,
input [15:0] di,
output reg [15:0] do,
input vclk,
input [14:0] vadr,
output [7:0] vdata
);

// 16384 x 16 bits = 32K

reg [15:0] mem[0:16383];

always @( posedge clk ) begin
if ( we != 0 )
mem[adr] <= di;
else
do <= mem[adr];
end

reg [15:0] q;

always @( posedge vclk ) begin
q <= mem[vadr>>1];
end

assign vdata = (vadr&1) ? q[7:0] : q[15:8];

endmodule
 
Also note that the code you have below does not describe this
Hmm. Yes- thanks for catching that. Easily solved by running the vadr[0]
through a D flip flop.
Unfortunately this still doesn't convince the synth to simplify the design
to a ram block with different bus sizes.
At this stage I'd rather the code stay succinct and portable, so I guess
I'll live with it.

Thanks,
Jason H.


"gabor" <gabor@alacron.com> wrote in message
news:1147981265.955001.289910@y43g2000cwc.googlegroups.com...
Hi Jason,

I think a synthesizer would need to be pretty smart to infer
a block ram with different port sizes. Also note that the code
you have below does not describe this. In the block ram
without an output mux, the data on the output would depend
on the address of the previous clock cycle. Your mux
is combinatorial and uses the LSB of the address on this clock
cycle. If a synthesis tool could infer a block RAM with two
different port sizes, you'd need to fix this.

Good Luck,
Gabor

deadsy wrote:
Hi:

I'm trying to define a dual port ram device with a 16kx16bit bus and a
32Kx8bit bus referring to the same memory.
The following gets the job done- but it uses a mux to select 8 of 16 for
the
8 bit data bus.
I'm using a Xilinx part and I understand the ram blocks can be setup with
different bus aspect ratios.
Is there a way to convince the synthesiser to do this in plain old
verilog,
without resorting to direct instantiation of the Xilinx ram block
primitive?

I'm a newbie to verilog- so I hope this isn't a dumb question.

Thanks,
Jason H.

module system_ram
(
input clk,
input we,
input [13:0] adr,
input [15:0] di,
output reg [15:0] do,
input vclk,
input [14:0] vadr,
output [7:0] vdata
);

// 16384 x 16 bits = 32K

reg [15:0] mem[0:16383];

always @( posedge clk ) begin
if ( we != 0 )
mem[adr] <= di;
else
do <= mem[adr];
end

reg [15:0] q;

always @( posedge vclk ) begin
q <= mem[vadr>>1];
end

assign vdata = (vadr&1) ? q[7:0] : q[15:8];

endmodule
 

Welcome to EDABoard.com

Sponsor

Back
Top