// // Copyright (c) 2014-2022 by 1801BM1@gmail.com // // DC304 MMU Chip Memory Managment Register File //______________________________________________________________________________ // // Generic implementation of Register File, memory blocks are supposed to be // inferred. Some verions of synthesys tools (Quartus, etc.) do not infer memory // blocks correctly, so explicit RAM megafunction should be used, depending on // device type. It provides much better Fmax and resource usage. If vendor // specific memory function is used this file should not be included in // the project. // // Interface is compatible with Altera Dual-Port Single Clock RAM with // byte lane enable strobes. // // Port A is used to access MMU registers from CPU bus and to present page // address register (PAR) content on address translation cycle. Port B is used // to present page descriptor register (PDR) content for address translation // and write Dirty Page flag back to PDR after memory write access. // module dc_mmu ( input clock, input [4:0] address_a, input [4:0] address_b, input [1:0] byteena_a, input [1:0] byteena_b, input [15:0] data_a, input [15:0] data_b, output [15:0] q_a, output [15:0] q_b, input wren_a, input wren_b ); reg [15:0] ram[31:0]; reg [5:0] addr_a; reg [5:0] addr_b; //______________________________________________________________________________ // // Minimal required registers initalization, otherwise, // undefined content would prevent simulation. // integer i; initial begin for (i=0; i<32; i = i+1) ram[i] = 16'h0000; end //______________________________________________________________________________ // always @ (posedge clock) begin addr_a = address_a; if (wren_a) begin if (byteena_a[0]) ram[addr_a][7:0] = data_a[7:0]; if (byteena_a[1]) ram[addr_a][15:8] = data_a[15:8]; end addr_b = address_b; if (wren_b) begin if (byteena_b[0]) ram[addr_b][7:0] = data_b[7:0]; if (byteena_b[1]) ram[addr_b][15:8] = data_b[15:8]; end end assign q_a = ram[addr_a]; assign q_b = ram[addr_b]; endmodule