Rom frisst ALMs

Gast #5185979
Lesenswert?

Hallo zusammen,

Ich versuche, per Verilog ein ROM zu erstellen, welches per Schalter 
umgeschaltet werden kann. Das Modul unten funktioniert soweit auch, die 
ROM belegen jedoch nicht BlockRam, sondern ALMs. Verwende ich das 
gleiche Modul mit fix einem Rom (case-Anweisung auskommentiert), wird 
wie gewünscht BlockRam verwendet.

Hat jemand eine Idee?

Ich verwende Quartus Prime Lite 17.0 mit dem Terasic Cyclone V Starter 
Board (mit mehr als genug BlockRam).

Besten Dank für die Hilfe :)

Benötigt ALMs:
1
module rom (
2
  input wire clk,
3
  input wire [12:0] address,
4
  input wire romSelect,
5
  output reg [7:0] dataOut
6
);
7

8
reg [7:0] rom0 [0:8191];
9
reg [7:0] rom1 [0:8191];
10

11
initial $readmemh("roms/rom0.hex",rom0);
12
initial $readmemh("roms/rom1.hex",rom1);
13

14
always @(posedge clk) begin
15
  case (romSelect)
16
    1'b0: dataOut <= rom0[address];
17
    1'b1: dataOut <= rom1[address];
18
  endcase  
19
end
20
  
21
endmodule

Alles wie gewünscht im BlockRam:
1
module rom (
2
  input wire clk,
3
  input wire [12:0] address,
4
  input wire romSelect,
5
  output reg [7:0] dataOut
6
);
7

8
reg [7:0] rom0 [0:8191];
9
reg [7:0] rom1 [0:8191];
10

11
initial $readmemh("roms/rom0.hex",rom0);
12
initial $readmemh("roms/rom1.hex",rom1);
13

14
always @(posedge clk) begin
15
//  case (romSelect)
16
//    1'b0: dataOut <= rom0[address];
17
//    1'b1: dataOut <= rom1[address];
18
//  endcase  
19
  dataOut <= rom0[address];
20
end
21
  
22
endmodule
#5186121
Lesenswert?

Lothar M. schrieb:
> Was schreibt denn Altera im Synthesizer Users Guide, wie man ein ROM in
> Verilog beschreiben muss, dass der Synthesizer dafür RAM-Blöcke nimmt?

Das hier:
1
// Single Port ROM
2

3
module single_port_rom
4
#(parameter DATA_WIDTH=8, parameter ADDR_WIDTH=8)
5
(
6
  input [(ADDR_WIDTH-1):0] addr,
7
  input clk, 
8
  output reg [(DATA_WIDTH-1):0] q
9
);
10

11
  // Declare the ROM variable
12
  reg [DATA_WIDTH-1:0] rom[2**ADDR_WIDTH-1:0];
13

14
  // Initialize the ROM with $readmemb.  Put the memory contents
15
  // in the file single_port_rom_init.txt.  Without this file,
16
  // this design will not compile.
17

18
  // See Verilog LRM 1364-2001 Section 17.2.8 for details on the
19
  // format of this file, or see the "Using $readmemb and $readmemh"
20
  // template later in this section.
21

22
  initial
23
  begin
24
    $readmemb("single_port_rom_init.txt", rom);
25
  end
26

27
  always @ (posedge clk)
28
  begin
29
    q <= rom[addr];
30
  end
31

32
endmodule

Lothar M. schrieb:
> Ich glaube, du musst den Multiplexer ausserhalb machen...

... das glaube ich auch. Oder Du nimmst ein doppelt grosses ROM und 
addierst beim Umschalten einfach einen Offset zur Adresse.
Gast #5186225
Lesenswert?

Multiplexer ausserhalb des ROM-Auslesens:
1
module rom (
2
  input wire clk,
3
  input wire [12:0] address,
4
  input wire romSelect,
5
  output reg [7:0] dataOut
6
);
7

8
reg [7:0] rom0 [0:8191];
9
reg [7:0] rom1 [0:8191];
10

11
initial $readmemh("roms/rom0.hex",rom0);
12
initial $readmemh("roms/rom1.hex",rom1);
13

14
wire [7:0] q0,q1;
15
 
16
always @(posedge clk) begin
17
  q0 <= rom0[address];
18
end
19

20
always @(posedge clk) begin
21
  q1 <= rom1[address];
22
end
23

24
assign dataOut = romSelect ? q1 : q0;
25
  
26
endmodule

Oder ein Rom mit umschalten der 2 Bereiche per MSB der Adresse:
1
module rom (
2
  input wire clk,
3
  input wire [12:0] address,
4
  input wire romSelect,
5
  output reg [7:0] dataOut
6
);
7

8
reg [7:0] rom0 [0:16383];
9

10
initial $readmemh("roms/rom0.hex",rom0,0);
11
initial $readmemh("roms/rom1.hex",rom0,8192);
12

13
 
14
always @(posedge clk) begin
15
  dataOut <= rom0[{romSelect,address}];
16
end
17
  
18
endmodule

Andi

P.S. Gibt es eigentlich ein Syntaxhighlighting für Verilog in diesem 
Forum?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren