Memories¶
Memories are either represented using RTLIL::Memory
objects, $memrd_v2
,
$memwr_v2
, and $meminit_v2
cells, or by $mem_v2
cells alone.
In the first alternative the RTLIL::Memory
objects hold the general metadata
for the memory (bit width, size in number of words, etc.) and for each port a
$memrd_v2
(read port) or $memwr_v2
(write port) cell is created. Having
individual cells for read and write ports has the advantage that they can be
consolidated using resource sharing passes. In some cases this drastically
reduces the number of required ports on the memory cell. In this alternative,
memory initialization data is represented by $meminit_v2
cells, which allow
delaying constant folding for initialization addresses and data until after the
frontend finishes.
The $memrd_v2
cells have a clock input CLK
, an enable input EN
, an
address input ADDR
, a data output DATA
, an asynchronous reset input
ARST
, and a synchronous reset input SRST
. They also have the following
parameters:
MEMID
The name of the
RTLIL::Memory
object that is associated with this read port.ABITS
The number of address bits (width of the
ADDR
input port).WIDTH
The number of data bits (width of the
DATA
output port). Note that this may be a power-of-two multiple of the underlying memory’s width – such ports are called wide ports and access an aligned group of cells at once. In this case, the corresponding low bits ofADDR
must be tied to 0.CLK_ENABLE
When this parameter is non-zero, the clock is used. Otherwise this read port is asynchronous and the
CLK
input is not used.CLK_POLARITY
Clock is active on the positive edge if this parameter has the value
1'b1
and on the negative edge if this parameter is1'b0
.TRANSPARENCY_MASK
This parameter is a bitmask of write ports that this read port is transparent with. The bits of this parameter are indexed by the write port’s
PORTID
parameter. Transparency can only be enabled between synchronous ports sharing a clock domain. When transparency is enabled for a given port pair, a read and write to the same address in the same cycle will return the new value. Otherwise the old value is returned.COLLISION_X_MASK
This parameter is a bitmask of write ports that have undefined collision behavior with this port. The bits of this parameter are indexed by the write port’s
PORTID
parameter. This behavior can only be enabled between synchronous ports sharing a clock domain. When undefined collision is enabled for a given port pair, a read and write to the same address in the same cycle will return the undefined (all-X) value.This option is exclusive (for a given port pair) with the transparency option.ARST_VALUE
Whenever the
ARST
input is asserted, the data output will be reset to this value. Only used for synchronous ports.SRST_VALUE
Whenever the
SRST
input is synchronously asserted, the data output will be reset to this value. Only used for synchronous ports.INIT_VALUE
The initial value of the data output, for synchronous ports.
CE_OVER_SRST
If this parameter is non-zero, the
SRST
input is only recognized whenEN
is true. Otherwise,SRST
is recognized regardless ofEN
.
The $memwr_v2
cells have a clock input CLK
, an enable input EN
(one
enable bit for each data bit), an address input ADDR
and a data input
DATA
. They also have the following parameters:
MEMID
The name of the
RTLIL::Memory
object that is associated with this write port.ABITS
The number of address bits (width of the
ADDR
input port).WIDTH
The number of data bits (width of the
DATA
output port). Like with$memrd_v2
cells, the width is allowed to be any power-of-two multiple of memory width, with the corresponding restriction on address.CLK_ENABLE
When this parameter is non-zero, the clock is used. Otherwise this write port is asynchronous and the
CLK
input is not used.CLK_POLARITY
Clock is active on positive edge if this parameter has the value
1'b1
and on the negative edge if this parameter is1'b0
.PORTID
An identifier for this write port, used to index write port bit mask parameters.
PRIORITY_MASK
This parameter is a bitmask of write ports that this write port has priority over in case of writing to the same address. The bits of this parameter are indexed by the other write port’s
PORTID
parameter. Write ports can only have priority over write ports with lower port ID. When two ports write to the same address and neither has priority over the other, the result is undefined. Priority can only be set between two synchronous ports sharing the same clock domain.
The $meminit_v2
cells have an address input ADDR
, a data input DATA
,
with the width of the DATA
port equal to WIDTH
parameter times WORDS
parameter, and a bit enable mask input EN
with width equal to WIDTH
parameter. All three of the inputs must resolve to a constant for synthesis to
succeed.
MEMID
The name of the
RTLIL::Memory
object that is associated with this initialization cell.ABITS
The number of address bits (width of the
ADDR
input port).WIDTH
The number of data bits per memory location.
WORDS
The number of consecutive memory locations initialized by this cell.
PRIORITY
The cell with the higher integer value in this parameter wins an initialization conflict.
The HDL frontend models a memory using RTLIL::Memory
objects and
asynchronous $memrd_v2
and $memwr_v2
cells. The memory
pass (i.e. its
various sub-passes) migrates $dff
cells into the $memrd_v2
and $memwr_v2
cells making them synchronous, then converts them to a single $mem_v2
cell and
(optionally) maps this cell type to $dff
cells for the individual words and
multiplexer-based address decoders for the read and write interfaces. When the
last step is disabled or not possible, a $mem_v2
cell is left in the design.
The $mem_v2
cell provides the following parameters:
MEMID
The name of the original
RTLIL::Memory
object that became this$mem_v2
cell.SIZE
The number of words in the memory.
ABITS
The number of address bits.
WIDTH
The number of data bits per word.
INIT
The initial memory contents.
RD_PORTS
The number of read ports on this memory cell.
RD_WIDE_CONTINUATION
This parameter is
RD_PORTS
bits wide, containing a bitmask of “wide continuation” read ports. Such ports are used to represent the extra data bits of wide ports in the combined cell, and must have all control signals identical with the preceding port, except for address, which must have the proper sub-cell address encoded in the low bits.RD_CLK_ENABLE
This parameter is
RD_PORTS
bits wide, containing a clock enable bit for each read port.RD_CLK_POLARITY
This parameter is
RD_PORTS
bits wide, containing a clock polarity bit for each read port.RD_TRANSPARENCY_MASK
This parameter is
RD_PORTS*WR_PORTS
bits wide, containing a concatenation of allTRANSPARENCY_MASK
values of the original$memrd_v2
cells.RD_COLLISION_X_MASK
This parameter is
RD_PORTS*WR_PORTS
bits wide, containing a concatenation of allCOLLISION_X_MASK
values of the original$memrd_v2
cells.RD_CE_OVER_SRST
This parameter is
RD_PORTS
bits wide, determining relative synchronous reset and enable priority for each read port.RD_INIT_VALUE
This parameter is
RD_PORTS*WIDTH
bits wide, containing the initial value for each synchronous read port.RD_ARST_VALUE
This parameter is
RD_PORTS*WIDTH
bits wide, containing the asynchronous reset value for each synchronous read port.RD_SRST_VALUE
This parameter is
RD_PORTS*WIDTH
bits wide, containing the synchronous reset value for each synchronous read port.WR_PORTS
The number of write ports on this memory cell.
WR_WIDE_CONTINUATION
This parameter is
WR_PORTS
bits wide, containing a bitmask of “wide continuation” write ports.WR_CLK_ENABLE
This parameter is
WR_PORTS
bits wide, containing a clock enable bit for each write port.WR_CLK_POLARITY
This parameter is
WR_PORTS
bits wide, containing a clock polarity bit for each write port.WR_PRIORITY_MASK
This parameter is
WR_PORTS*WR_PORTS
bits wide, containing a concatenation of allPRIORITY_MASK
values of the original$memwr_v2
cells.
The $mem_v2
cell has the following ports:
RD_CLK
This input is
RD_PORTS
bits wide, containing all clock signals for the read ports.RD_EN
This input is
RD_PORTS
bits wide, containing all enable signals for the read ports.RD_ADDR
This input is
RD_PORTS*ABITS
bits wide, containing all address signals for the read ports.RD_DATA
This output is
RD_PORTS*WIDTH
bits wide, containing all data signals for the read ports.RD_ARST
This input is
RD_PORTS
bits wide, containing all asynchronous reset signals for the read ports.RD_SRST
This input is
RD_PORTS
bits wide, containing all synchronous reset signals for the read ports.WR_CLK
This input is
WR_PORTS
bits wide, containing all clock signals for the write ports.WR_EN
This input is
WR_PORTS*WIDTH
bits wide, containing all enable signals for the write ports.WR_ADDR
This input is
WR_PORTS*ABITS
bits wide, containing all address signals for the write ports.WR_DATA
This input is
WR_PORTS*WIDTH
bits wide, containing all data signals for the write ports.
The memory_collect
pass can be used to convert discrete $memrd_v2
,
$memwr_v2
, and $meminit_v2
cells belonging to the same memory to a single
$mem_v2
cell, whereas the memory_unpack
pass performs the inverse operation.
The memory_dff
pass can combine asynchronous memory ports that are fed by or
feeding registers into synchronous memory ports. The memory_bram
pass can be
used to recognize $mem_v2
cells that can be implemented with a block RAM
resource on an FPGA. The memory_map
pass can be used to implement $mem_v2
cells as basic logic: word-wide DFFs and address decoders.
- yosys> help $mem¶
- Simulation model (verilog)¶
2934module \$mem (RD_CLK, RD_EN, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); 2935 2936 parameter MEMID = ""; 2937 parameter signed SIZE = 4; 2938 parameter signed OFFSET = 0; 2939 parameter signed ABITS = 2; 2940 parameter signed WIDTH = 8; 2941 parameter signed INIT = 1'bx; 2942 2943 parameter signed RD_PORTS = 1; 2944 parameter RD_CLK_ENABLE = 1'b1; 2945 parameter RD_CLK_POLARITY = 1'b1; 2946 parameter RD_TRANSPARENT = 1'b1; 2947 2948 parameter signed WR_PORTS = 1; 2949 parameter WR_CLK_ENABLE = 1'b1; 2950 parameter WR_CLK_POLARITY = 1'b1; 2951 2952 input [RD_PORTS-1:0] RD_CLK; 2953 input [RD_PORTS-1:0] RD_EN; 2954 input [RD_PORTS*ABITS-1:0] RD_ADDR; 2955 output reg [RD_PORTS*WIDTH-1:0] RD_DATA; 2956 2957 input [WR_PORTS-1:0] WR_CLK; 2958 input [WR_PORTS*WIDTH-1:0] WR_EN; 2959 input [WR_PORTS*ABITS-1:0] WR_ADDR; 2960 input [WR_PORTS*WIDTH-1:0] WR_DATA; 2961 2962 reg [WIDTH-1:0] memory [SIZE-1:0]; 2963 2964 integer i, j; 2965 reg [WR_PORTS-1:0] LAST_WR_CLK; 2966 reg [RD_PORTS-1:0] LAST_RD_CLK; 2967 2968 function port_active; 2969 input clk_enable; 2970 input clk_polarity; 2971 input last_clk; 2972 input this_clk; 2973 begin 2974 casez ({clk_enable, clk_polarity, last_clk, this_clk}) 2975 4'b0???: port_active = 1; 2976 4'b1101: port_active = 1; 2977 4'b1010: port_active = 1; 2978 default: port_active = 0; 2979 endcase 2980 end 2981 endfunction 2982 2983 initial begin 2984 for (i = 0; i < SIZE; i = i+1) 2985 memory[i] = INIT >>> (i*WIDTH); 2986 end 2987 2988 always @(RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA) begin 2989 `ifdef SIMLIB_MEMDELAY 2990 #`SIMLIB_MEMDELAY; 2991 `endif 2992 for (i = 0; i < RD_PORTS; i = i+1) begin 2993 if (!RD_TRANSPARENT[i] && RD_CLK_ENABLE[i] && RD_EN[i] && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) begin 2994 // $display("Read from %s: addr=%b data=%b", MEMID, RD_ADDR[i*ABITS +: ABITS], memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]); 2995 RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; 2996 end 2997 end 2998 2999 for (i = 0; i < WR_PORTS; i = i+1) begin 3000 if (port_active(WR_CLK_ENABLE[i], WR_CLK_POLARITY[i], LAST_WR_CLK[i], WR_CLK[i])) 3001 for (j = 0; j < WIDTH; j = j+1) 3002 if (WR_EN[i*WIDTH+j]) begin 3003 // $display("Write to %s: addr=%b data=%b", MEMID, WR_ADDR[i*ABITS +: ABITS], WR_DATA[i*WIDTH+j]); 3004 memory[WR_ADDR[i*ABITS +: ABITS] - OFFSET][j] = WR_DATA[i*WIDTH+j]; 3005 end 3006 end 3007 3008 for (i = 0; i < RD_PORTS; i = i+1) begin 3009 if ((RD_TRANSPARENT[i] || !RD_CLK_ENABLE[i]) && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) begin 3010 // $display("Transparent read from %s: addr=%b data=%b", MEMID, RD_ADDR[i*ABITS +: ABITS], memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]); 3011 RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; 3012 end 3013 end 3014 3015 LAST_RD_CLK <= RD_CLK; 3016 LAST_WR_CLK <= WR_CLK; 3017 end 3018 3019endmodule
- yosys> help $mem_v2¶
- Simulation model (verilog)¶
3023module \$mem_v2 (RD_CLK, RD_EN, RD_ARST, RD_SRST, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); 3024 3025 parameter MEMID = ""; 3026 parameter signed SIZE = 4; 3027 parameter signed OFFSET = 0; 3028 parameter signed ABITS = 2; 3029 parameter signed WIDTH = 8; 3030 parameter signed INIT = 1'bx; 3031 3032 parameter signed RD_PORTS = 1; 3033 parameter RD_CLK_ENABLE = 1'b1; 3034 parameter RD_CLK_POLARITY = 1'b1; 3035 parameter RD_TRANSPARENCY_MASK = 1'b0; 3036 parameter RD_COLLISION_X_MASK = 1'b0; 3037 parameter RD_WIDE_CONTINUATION = 1'b0; 3038 parameter RD_CE_OVER_SRST = 1'b0; 3039 parameter RD_ARST_VALUE = 1'b0; 3040 parameter RD_SRST_VALUE = 1'b0; 3041 parameter RD_INIT_VALUE = 1'b0; 3042 3043 parameter signed WR_PORTS = 1; 3044 parameter WR_CLK_ENABLE = 1'b1; 3045 parameter WR_CLK_POLARITY = 1'b1; 3046 parameter WR_PRIORITY_MASK = 1'b0; 3047 parameter WR_WIDE_CONTINUATION = 1'b0; 3048 3049 input [RD_PORTS-1:0] RD_CLK; 3050 input [RD_PORTS-1:0] RD_EN; 3051 input [RD_PORTS-1:0] RD_ARST; 3052 input [RD_PORTS-1:0] RD_SRST; 3053 input [RD_PORTS*ABITS-1:0] RD_ADDR; 3054 output reg [RD_PORTS*WIDTH-1:0] RD_DATA; 3055 3056 input [WR_PORTS-1:0] WR_CLK; 3057 input [WR_PORTS*WIDTH-1:0] WR_EN; 3058 input [WR_PORTS*ABITS-1:0] WR_ADDR; 3059 input [WR_PORTS*WIDTH-1:0] WR_DATA; 3060 3061 reg [WIDTH-1:0] memory [SIZE-1:0]; 3062 3063 integer i, j, k; 3064 reg [WR_PORTS-1:0] LAST_WR_CLK; 3065 reg [RD_PORTS-1:0] LAST_RD_CLK; 3066 3067 function port_active; 3068 input clk_enable; 3069 input clk_polarity; 3070 input last_clk; 3071 input this_clk; 3072 begin 3073 casez ({clk_enable, clk_polarity, last_clk, this_clk}) 3074 4'b0???: port_active = 1; 3075 4'b1101: port_active = 1; 3076 4'b1010: port_active = 1; 3077 default: port_active = 0; 3078 endcase 3079 end 3080 endfunction 3081 3082 initial begin 3083 for (i = 0; i < SIZE; i = i+1) 3084 memory[i] = INIT >>> (i*WIDTH); 3085 RD_DATA = RD_INIT_VALUE; 3086 end 3087 3088 always @(RD_CLK, RD_ARST, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA) begin 3089 `ifdef SIMLIB_MEMDELAY 3090 #`SIMLIB_MEMDELAY; 3091 `endif 3092 for (i = 0; i < RD_PORTS; i = i+1) begin 3093 if (RD_CLK_ENABLE[i] && RD_EN[i] && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) begin 3094 // $display("Read from %s: addr=%b data=%b", MEMID, RD_ADDR[i*ABITS +: ABITS], memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]); 3095 RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; 3096 3097 for (j = 0; j < WR_PORTS; j = j+1) begin 3098 if (RD_TRANSPARENCY_MASK[i*WR_PORTS + j] && port_active(WR_CLK_ENABLE[j], WR_CLK_POLARITY[j], LAST_WR_CLK[j], WR_CLK[j]) && RD_ADDR[i*ABITS +: ABITS] == WR_ADDR[j*ABITS +: ABITS]) 3099 for (k = 0; k < WIDTH; k = k+1) 3100 if (WR_EN[j*WIDTH+k]) 3101 RD_DATA[i*WIDTH+k] <= WR_DATA[j*WIDTH+k]; 3102 if (RD_COLLISION_X_MASK[i*WR_PORTS + j] && port_active(WR_CLK_ENABLE[j], WR_CLK_POLARITY[j], LAST_WR_CLK[j], WR_CLK[j]) && RD_ADDR[i*ABITS +: ABITS] == WR_ADDR[j*ABITS +: ABITS]) 3103 for (k = 0; k < WIDTH; k = k+1) 3104 if (WR_EN[j*WIDTH+k]) 3105 RD_DATA[i*WIDTH+k] <= 1'bx; 3106 end 3107 end 3108 end 3109 3110 for (i = 0; i < WR_PORTS; i = i+1) begin 3111 if (port_active(WR_CLK_ENABLE[i], WR_CLK_POLARITY[i], LAST_WR_CLK[i], WR_CLK[i])) 3112 for (j = 0; j < WIDTH; j = j+1) 3113 if (WR_EN[i*WIDTH+j]) begin 3114 // $display("Write to %s: addr=%b data=%b", MEMID, WR_ADDR[i*ABITS +: ABITS], WR_DATA[i*WIDTH+j]); 3115 memory[WR_ADDR[i*ABITS +: ABITS] - OFFSET][j] = WR_DATA[i*WIDTH+j]; 3116 end 3117 end 3118 3119 for (i = 0; i < RD_PORTS; i = i+1) begin 3120 if (!RD_CLK_ENABLE[i]) begin 3121 // $display("Combinatorial read from %s: addr=%b data=%b", MEMID, RD_ADDR[i*ABITS +: ABITS], memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]); 3122 RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; 3123 end 3124 end 3125 3126 for (i = 0; i < RD_PORTS; i = i+1) begin 3127 if (RD_SRST[i] && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i]) && (RD_EN[i] || !RD_CE_OVER_SRST[i])) 3128 RD_DATA[i*WIDTH +: WIDTH] <= RD_SRST_VALUE[i*WIDTH +: WIDTH]; 3129 if (RD_ARST[i]) 3130 RD_DATA[i*WIDTH +: WIDTH] <= RD_ARST_VALUE[i*WIDTH +: WIDTH]; 3131 end 3132 3133 LAST_RD_CLK <= RD_CLK; 3134 LAST_WR_CLK <= WR_CLK; 3135 end 3136 3137endmodule
- yosys> help $meminit¶
- Simulation model (verilog)¶
2885module \$meminit (ADDR, DATA); 2886 2887 parameter MEMID = ""; 2888 parameter ABITS = 8; 2889 parameter WIDTH = 8; 2890 parameter WORDS = 1; 2891 2892 parameter PRIORITY = 0; 2893 2894 input [ABITS-1:0] ADDR; 2895 input [WORDS*WIDTH-1:0] DATA; 2896 2897 initial begin 2898 if (MEMID != "") begin 2899 $display("ERROR: Found non-simulatable instance of $meminit!"); 2900 $finish; 2901 end 2902 end 2903 2904endmodule
- yosys> help $meminit_v2¶
- Simulation model (verilog)¶
2909module \$meminit_v2 (ADDR, DATA, EN); 2910 2911 parameter MEMID = ""; 2912 parameter ABITS = 8; 2913 parameter WIDTH = 8; 2914 parameter WORDS = 1; 2915 2916 parameter PRIORITY = 0; 2917 2918 input [ABITS-1:0] ADDR; 2919 input [WORDS*WIDTH-1:0] DATA; 2920 input [WIDTH-1:0] EN; 2921 2922 initial begin 2923 if (MEMID != "") begin 2924 $display("ERROR: Found non-simulatable instance of $meminit_v2!"); 2925 $finish; 2926 end 2927 end 2928 2929endmodule
- yosys> help $memrd¶
- Simulation model (verilog)¶
2776module \$memrd (CLK, EN, ADDR, DATA); 2777 2778 parameter MEMID = ""; 2779 parameter ABITS = 8; 2780 parameter WIDTH = 8; 2781 2782 parameter CLK_ENABLE = 0; 2783 parameter CLK_POLARITY = 0; 2784 parameter TRANSPARENT = 0; 2785 2786 input CLK, EN; 2787 input [ABITS-1:0] ADDR; 2788 output [WIDTH-1:0] DATA; 2789 2790 initial begin 2791 if (MEMID != "") begin 2792 $display("ERROR: Found non-simulatable instance of $memrd!"); 2793 $finish; 2794 end 2795 end 2796 2797endmodule
- yosys> help $memrd_v2¶
- Simulation model (verilog)¶
2801module \$memrd_v2 (CLK, EN, ARST, SRST, ADDR, DATA); 2802 2803 parameter MEMID = ""; 2804 parameter ABITS = 8; 2805 parameter WIDTH = 8; 2806 2807 parameter CLK_ENABLE = 0; 2808 parameter CLK_POLARITY = 0; 2809 parameter TRANSPARENCY_MASK = 0; 2810 parameter COLLISION_X_MASK = 0; 2811 parameter ARST_VALUE = 0; 2812 parameter SRST_VALUE = 0; 2813 parameter INIT_VALUE = 0; 2814 parameter CE_OVER_SRST = 0; 2815 2816 input CLK, EN, ARST, SRST; 2817 input [ABITS-1:0] ADDR; 2818 output [WIDTH-1:0] DATA; 2819 2820 initial begin 2821 if (MEMID != "") begin 2822 $display("ERROR: Found non-simulatable instance of $memrd_v2!"); 2823 $finish; 2824 end 2825 end 2826 2827endmodule
- yosys> help $memwr¶
- Simulation model (verilog)¶
2832module \$memwr (CLK, EN, ADDR, DATA); 2833 2834 parameter MEMID = ""; 2835 parameter ABITS = 8; 2836 parameter WIDTH = 8; 2837 2838 parameter CLK_ENABLE = 0; 2839 parameter CLK_POLARITY = 0; 2840 parameter PRIORITY = 0; 2841 2842 input CLK; 2843 input [WIDTH-1:0] EN; 2844 input [ABITS-1:0] ADDR; 2845 input [WIDTH-1:0] DATA; 2846 2847 initial begin 2848 if (MEMID != "") begin 2849 $display("ERROR: Found non-simulatable instance of $memwr!"); 2850 $finish; 2851 end 2852 end 2853 2854endmodule
- yosys> help $memwr_v2¶
- Simulation model (verilog)¶
2857module \$memwr_v2 (CLK, EN, ADDR, DATA); 2858 2859 parameter MEMID = ""; 2860 parameter ABITS = 8; 2861 parameter WIDTH = 8; 2862 2863 parameter CLK_ENABLE = 0; 2864 parameter CLK_POLARITY = 0; 2865 parameter PORTID = 0; 2866 parameter PRIORITY_MASK = 0; 2867 2868 input CLK; 2869 input [WIDTH-1:0] EN; 2870 input [ABITS-1:0] ADDR; 2871 input [WIDTH-1:0] DATA; 2872 2873 initial begin 2874 if (MEMID != "") begin 2875 $display("ERROR: Found non-simulatable instance of $memwr_v2!"); 2876 $finish; 2877 end 2878 end 2879 2880endmodule