module memory_3(dout,err,addr,size,we,din,clk); input [31:0] addr; input [1:0] size; input we; input [31:0] din; input clk; output [31:0] dout; output [2:0] err; reg [31:0] dout; reg [2:0] err; parameter text_base = 'h400000; parameter text_size = 'h100; parameter data_base = 'h10010000; parameter data_size = 'h100; parameter err_none = 0; parameter err_bus = 1; // Bad alignment. parameter err_seg = 2; // Bad address. reg [31:0] storage [0:(text_size+data_size)>>2]; reg [31:0] saddr, mask, rd; reg [4:0] amt; function [31:0] addr_to_saddr; input [31:0] a; if( a >= text_base && a < text_base + text_size ) begin addr_to_saddr = a - text_base >> 2; end else if( a >= data_base && a < data_base + data_size ) begin addr_to_saddr = a - data_base + text_size >> 2; end else begin addr_to_saddr = -1; end endfunction reg [2:0] access_mem_err; function [31:0] access_mem; input [31:0] addr; input [1:0] size; input we; input [31:0] din; begin saddr = addr_to_saddr(addr); if( !size ) begin access_mem_err = err_none; access_mem = 0; end else if( saddr == -1 ) begin access_mem_err = err_seg; access_mem = 32'bz; end else begin access_mem_err = addr << 3 - size & 3 ? err_bus : err_none; amt = 3 - addr[1:0] - { &size, size[1] } << 3; mask = ( ( 1 << ( 8 << (size-1) ) ) - 1 ) << amt; rd = storage[ saddr ]; access_mem = err == err_bus ? 32'bzx : ( rd & mask ) >> amt; if( we ) storage[ saddr ] = ( rd & ~mask ) | ( (din<<amt ) & mask ); end end endfunction function [31:0] peek_word; input [31:0] peek_addr; peek_word = access_mem(peek_addr,3,0,0); endfunction function [2:0] poke_word; input [31:0] poke_addr; input [31:0] poke_data; reg [31:0] dummy; begin dummy = access_mem(poke_addr,3,1,poke_data); poke_word = access_mem_err; end endfunction always @( negedge clk ) begin dout = access_mem(addr,size,we,din); err = access_mem_err; end endmodule