/* Behavioural of our SRAM chips */ module sim_sram512x16(input [18:0] addr, input _cs, input _oe, input _we, input _ub, input _lb, inout [15:0] data); reg sel; reg [15:0] mem[0:'h7ffff]; reg [15:0] dlatch; wire [15:0] dout; /* Simplified model, roughly based on a IS64LV6416L model adapted * to look like our AS6C8016 */ parameter Taa = 55; parameter Toh = 10; parameter Tchz = 20; parameter Tas = 0; parameter Twhz = 20; wire r_en = _we & (~_cs) & (~_oe); wire w_en = (~_we) & (~_cs) & ((~_ub) | (~_lb)); assign #(r_en ? Taa : Tchz) data = r_en ? dout : 16'bz; assign dout[ 7:0] = _lb ? 8'bz : mem[addr][ 7:0]; assign dout[15:8] = _ub ? 8'bz : mem[addr][15:8]; always@(addr or w_en) begin #Tas if (w_en) #Twhz begin /* XXX Something's wrong with iverilog. It appears that * the if (w_en) above isn't enough, if I don't also test * w_en in the assignment belwow, it -will- write spuriously * to the RAMs even when w_en has never kicked for a while * and I really have no idea why. --BenH */ mem[addr][ 7:0] = _lb | ~w_en ?mem[addr][ 7:0] : data[ 7:0]; mem[addr][15:8] = _ub | ~w_en ?mem[addr][15:8] : data[15:8]; end end `ifdef foo initial begin $display("initializing RAM..."); mem[0] = 0; mem[1] = 'h2000 - 16; mem[2] = 0; mem[3] = 'h1000; // 1000: 303c 000a movew #10,%d0 mem['h1000/2] = 'h303c; mem['h1002/2] = 'h000a; // 1004: 41fa 001a lea %pc@(1020 <_buf>),%a0 mem['h1004/2] = 'h41fa; mem['h1006/2] = 'h001a; // 1008: 3080 movew %d0,%a0@ mem['h1008/2] = 'h3080; // 100a: 0640 0001 addiw #1,%d0 mem['h100a/2] = 'h0640; mem['h100c/2] = 'h0001; // 100e: 6000 fff4 braw 1004 mem['h100e/2] = 'h6000; mem['h1010/2] = 'hfff4; $display("done"); end // initial begin `endif endmodule