// High-level memory module demonstration // Assignment 7 for COMP231, 4/5/01 // by Julian Graham // I've dropped any pretenses I had that I could do this logically... So, // although I regret it, the flipflop module uses a whole bunch of ugly // Verilog abstractions. // Here's our clock. It has a period of 4 Verilog "cycles," 2 for, 2 // high. Of course, real clocks don't display obnoxious strings, but I // thought it would be useful for the demonstration. Interestingly // enough, Verilog, or at least, Veriwell, seems to consider the // transition from "x" to "0" a negative edge. module clock (out); output out; reg crystal_oscillator; always begin #1 crystal_oscillator = 0; #1 crystal_oscillator = 0; #1 crystal_oscillator = 1; #1 crystal_oscillator = 1; end always @(posedge crystal_oscillator) begin $display ("Approaching positive edge..."); end always @(negedge crystal_oscillator) begin $display ("Approaching negative edge..."); end assign out = crystal_oscillator; endmodule // Here's our 1-bit NEFF. If the control is set high, we can write data, // once the clock hits the negative edge. Otherwise, there's no change to // the value of the register (which supplants whatever kind of latch-like // structure I was planning to use). When the control is set high, the // output is x, when it's low, indicating that we want to read, the output // is the value of the register. I suppose it's a slightly irritating // constraint, but I thought it would be an interesting one for the sake // of demonstration. module neff (clock_bit, data, out, control); input clock_bit, data, control; output out; reg cell; wire cell_buffer; always @(negedge clock_bit) begin if (control == 1) begin cell = data; end end assign out = ((control & 1'hx) | cell) & (~control | 1'hx); endmodule // Our memory module is merely a collection of NEFFs. Not too much to say // about this one... module memory (clock_bit, in, out, control); parameter N = 6; input [N - 1 : 0] in; input clock_bit, control; output [N - 1 : 0] out; neff bit1 (clock_bit, in [0], out [0], control); neff bit2 (clock_bit, in [1], out [1], control); neff bit3 (clock_bit, in [2], out [2], control); neff bit4 (clock_bit, in [3], out [3], control); neff bit5 (clock_bit, in [4], out [4], control); neff bit6 (clock_bit, in [5], out [5], control); endmodule // Our main module, for demonstration. We create an instantiation of our // clock and our memory chip, and we try and store and read a couple of // values. Interestingly enough, it DOES take 2 time units in Verilog to // actually store the values... if we try and read right after we write, // we get "xxxxxx." The $display messages don't sync up the way I'd like // them to in the output, but the lines should get set at the appropriate // moments. module demonstration; parameter N = 6; reg [N - 1 : 0] in; wire [N - 1 : 0] out; reg control; wire clock_bit; clock clock1 (clock_bit); memory memory1 (clock_bit, in, out, control); initial begin #4 control = 1; in = 26; $display ("Attempting to store decimal value %d...", in); #2 control = 0; $display ("Attempting to read stored value..."); #1 control = 1; in = 47; $display ("Attempting to store decimal value %d...", in); #2 control = 0; $display ("Attempting to read stored value..."); #1 $finish; end initial begin $monitor ("clock level : %b, control : %b, data line : %b (%d), mem output : %b (%d)", clock_bit, control, in, in, out, out); end endmodule