1 // -----------------------------------------------------------------------
3 // Copyright 2004 Tommy Thorn - All Rights Reserved
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 // Bostom MA 02111-1307, USA; either version 2 of the License, or
9 // (at your option) any later version; incorporated herein by reference.
11 // -----------------------------------------------------------------------
14 * Simulate the Altera Sync RAM (AltSyncRAM)
16 * Not very ambitious, just the bare minimum.
24 module altsyncram(clocken0
,
34 parameter intended_device_family
= "Cyclone";
35 parameter width_a
= 32;
36 parameter width_b
= 32;
37 parameter widthad_a
= 11;
38 parameter widthad_b
= 11;
39 parameter numwords_a
= 2048;
40 parameter numwords_b
= 2048;
41 parameter operation_mode
= "SINGLE_PORT";
42 parameter outdata_reg_a
= "UNREGISTERED";
43 parameter indata_aclr_a
= "NONE";
44 parameter wrcontrol_aclr_a
= "NONE";
45 parameter address_aclr_a
= "NONE";
46 parameter outdata_aclr_a
= "NONE";
47 parameter width_byteena_a
= 4;
48 parameter byte_size
= 0;
49 parameter byteena_aclr_a
= "NONE";
50 parameter ram_block_type
= "AUTO";
51 parameter init_file
= "dcache.mif";
52 parameter lpm_type
= "altsyncram";
55 parameter address_aclr_b
= "NONE";
56 parameter address_reg_b
= "CLOCK0";
57 parameter outdata_aclr_b
= "NONE";
58 parameter outdata_reg_b
= "UNREGISTERED";
59 parameter read_during_write_mode_mixed_ports
= "DONT_CARE";
66 input wire [width_byteena_a
-1:0] byteena_a
;
67 input wire [widthad_a
-1:0] address_a
;
68 input wire [widthad_b
-1:0] address_b
;
69 input wire [width_a
-1:0] data_a
;
70 output wire [width_a
-1:0] q_a
;
71 output wire [width_b
-1:0] q_b
;
73 reg [width_a
-1:0] ram
[numwords_a
-1:0];
75 reg [widthad_a
-1:0] addr_a_delayed
;
76 reg [width_a
-1:0] data_a_delayed
;
78 reg [3:0] byteena_a_delayed
;
80 reg [widthad_b
-1:0] addr_b_delayed
;
81 reg [width_b
-1:0] data_b_delayed
;
83 reg [3:0] byteena_b_delayed
;
85 wire [width_a
-1:0] wr_mask
=
87 ?
{{8{byteena_a_delayed
[3]}},
88 {8{byteena_a_delayed
[2]}},
89 {8{byteena_a_delayed
[1]}},
90 {8{byteena_a_delayed
[0]}}}
93 always @(posedge clock0
) begin
94 if (clocken0 | byte_size
== 0) begin
95 data_a_delayed
<= data_a
;
96 addr_a_delayed
<= address_a
;
97 addr_b_delayed
<= address_b
;
98 wren_a_delayed
<= wren_a
;
99 byteena_a_delayed
<= byteena_a
;
101 if (debug
&& operation_mode
== "DUAL_PORT") begin
102 $display("%5d altsyncram a: (%x) ram[%x] = %x", $time, address_a
, addr_a_delayed
, q_a
);
103 $display("%5d altsyncram b: (%x) ram[%x] = %x", $time, address_b
, addr_b_delayed
, q_b
);
106 $display("%5d altsyncram ram[%x] <= %x",
107 $time, addr_a_delayed
,
108 data_a_delayed
& wr_mask |
109 ram
[addr_a_delayed
] & ~wr_mask
);
112 // XXX 2005-06-20: As far as I can tell all this shouldn't
113 // have used delayed signals!
114 if (wren_a_delayed
) begin
116 ram
[addr_a_delayed
] <=
117 data_a_delayed
& wr_mask | ram
[addr_a_delayed
] & ~wr_mask
;
122 assign q_a
= ram
[addr_a_delayed
];
123 assign q_b
= ram
[addr_b_delayed
];