Proposed styles for Inferring ROMs in Verilog


Subject: Proposed styles for Inferring ROMs in Verilog
From: VhdlCohen@aol.com
Date: Fri Jul 06 2001 - 19:05:11 PDT


Following are 3 styles for potentially inferring ROMs:
1. CASE of address with assignment to vector output.
2. Initial statement of a memory object, values are in Verilog code.
3. Initial statement with memory initialized with $readmemb or $readmemh.
     ROM data is in a file.

Comments, suggestions, additions are welcomed. This is only a proposal.

/* -----\/----- EXCLUDED -----\/-----
From LRM 2.8 Attributes
Syntax for attributes
attribute_instance ::= (* attr_spec {,attr_spec} *)
attr_spec ::=
  attr_name = constant_expression
  | attr_name
 -----/\----- EXCLUDED -----/\----- */
 
// ALL coded compiles ok with ncsim and modelsim

// ROM module using one dimentional array with CASE statement
// Currently implemmented by Synplify
module rom_case(z, a);
  output [3:0] z; // 4 wide
  input [2:0] a; // address. 8 deep memory
  // proposed syntax
  reg [3:0] z /* syn_romstyle = block_rom */;
  // Other potentials
  // /* syn_romstyle = 1 */
  // NOTE: To infer combinational logic instead of ROM, use
  // /* syn_romstyle = logic */
  always @(a) begin
    case (a)
      3'b000: z = 4'b1011;
      3'b001: z = 4'b0001;
      3'b100: z = 4'b0011;
      3'b110: z = 4'b0010;
      3'b111: z = 4'b1110;
      default: z = 4'b0000;
    endcase
  end
endmodule // rom_case

// --------------------
// ROM module using two dimentional arrays with
// memory defined in "INITAL" statement
// NOTE: This style emulates the VHDL initialization
// of a memory array constant.
// constant ROM : Rom_typ :=
// ( 0 => "0101",
// 1 => "1010",
// others => "0000");
module rom_2dimarray_inital (z, a);
  output [3:0] z;
  input [2:0] a;
  // proposed syntax
  reg [3:0] rom[0:7] /* syn_romstyle = block_rom */;
  // declares a memory rom of 8 4-bit
  // registers. The indices are 0 to 7
  // NOTE: To infer combinational logic instead of ROM, use
  // /* syn_romstyle = logic */
  initial begin
    rom[0] = 4'b1011;
    rom[1] = 4'b0001;
    rom[2] = 4'b0011;
    rom[3] = 4'b0010;
    rom[4] = 4'b1110;
    rom[5] = 4'b0111;
    rom[6] = 4'b0101;
    rom[7] = 4'b0100;
  end
  
  assign z = rom[a];
   
endmodule

// --------------------
// ROM module using two dimentional arrays with
// memory defined in textfile with $readmemb or $readmemh
// NOTE: This style can lead to simulation/sythesis mismatch
// if the content of data file changes after synthesis
// Also (per 1997 documentation)
// Xilinx uses memgen to create an XNF file to create a rom with rom data
// stored in a file. This is a tool specific solution.
module rom_2dimarray_initial_readmem (z, a);
  output [3:0] z;
  input [2:0] a;
  // proposed syntax
  reg [3:0] rom[0:7] /* syn_romstyle = block_rom */;
  // declares a memory rom of 8 4-bit
  // registers. The indices are 0 to 7
  // NOTE: To infer combinational logic instead of ROM, use
  // /* syn_romstyle = logic */
  initial begin
    $readmemb("rom.data", rom);
  end

  assign z = rom[a];
   
endmodule
  

------------------------------------------------------------------------------

--------------------------------------
Ben Cohen     Publisher, Trainer, Consultant    (310) 721-4830
http://www.vhdlcohen.com/                 vhdlcohen@aol.com  
Author of following textbooks:
* Component Design by Example ... a Step-by-Step Process Using
  VHDL with UART as Vehicle",  2001 isbn  0-9705394-0-1
* VHDL Coding Styles and Methodologies, 2nd Edition, 1999 isbn 0-7923-8474-1
* VHDL Answers to Frequently Asked Questions, 2nd Edition, isbn 0-7923-8115
------------------------------------------------------------------------------

--------------------------------------



This archive was generated by hypermail 2b28 : Fri Jul 06 2001 - 19:20:19 PDT