// // // This circuit generates WE pulses. For example, if you have a chip that // needs to access an asynchronous SRAM in a single cycle and you wanted // generate the WE pulse synchronous with your system clock. // // Every clk cycle, generate an active // low WE pulse. The delay from the clk rising edge to the falling edge of // we is based on abits setting, which affects delay taps, etc. Likewise, // bbits controls the following rising edge of we. The module contains // two flip flops that generate two opposite poraity toggling levels. // A delay chain is attached to each of these outputs. The abits and bbits // get the desired tap, and the final two delayed signals are XORed together // to get the final we. None of this is very tuned, you would look at your // cycle time and pick a delay chain that makes sense for that. But, this // shows the effect. // // The we pulse always occurs. You will probably want to combine this with // you write_enable signal. This sort of circuit is, of course, highly dependent // on post-layout timing, etc. but that's why its programable. You probably // want more taps, too.. // // module wpulse ( reset, clk, abits, bbits, we ); input clk; input reset; input [3:0] abits; // bits to select which delay tap to use for first edge input [3:0] bbits; // bits to select which delay tap to use for pulse width output we; reg p1, p2; wire adel1out; wire adel2out; wire adel3out; wire adel4out; wire bdel1out; wire bdel2out; wire bdel3out; wire bdel4out; wire adelout; wire bdelout; // 2 flip-flops that are opposite polarity. Each flop toggles // every cycles. // always @(posedge clk) p1 <= (reset) | (~reset & ~p1); // reset to 1 always @(posedge clk) p2 <= (~reset & ~p2); // reset to 0 // Delay chain off of the p1 flop. delay4 adel1 (.a(p1), .z(adel1out)); delay4 adel2 (.a(adel1out), .z(adel2out)); delay4 adel3 (.a(adel2out), .z(adel3out)); delay4 adel4 (.a(adel3out), .z(adel4out)); // Delay chain off of the p2 flop. delay4 bdel1 (.a(p2), .z(bdel1out)); delay4 bdel2 (.a(bdel1out), .z(bdel2out)); delay4 bdel3 (.a(bdel2out), .z(bdel3out)); delay4 bdel4 (.a(bdel3out), .z(bdel4out)); // Select the tap of the p1 and p2 delay chains we want based on abits assign adelout = abits[3] & adel1out | abits[2] & adel2out | abits[1] & adel3out | abits[0] & adel4out; assign bdelout = bbits[3] & bdel1out | bbits[2] & bdel2out | bbits[1] & bdel3out | bbits[0] & bdel4out; // Final we pulse is just the XOR of the two chains. assign we = adelout ^ bdelout; endmodule // This is our delay cell. Pick whatever cell makes sense from your library. module delay4 (a, z); input a; output z; reg z; always @(a) z = #4 a; endmodule // synopsys translate_off module testwpulse; reg clk; reg reset; reg [3:0] abits; // bits to select which delay tap to use for first edge reg [3:0] bbits; // bits to select which delay tap to use for pulse width wire we; wpulse wpulse_inst ( .reset (reset), .clk (clk), .abits (abits), .bbits (bbits), .we (we) ); initial begin abits = 4'b1000; // Shortest pulse, earliest in cycle. bbits = 4'b0100; #200; abits = 4'b0010; // Shortest pulse, latest in the cycle. bbits = 4'b0001; #200; abits = 4'b0100; // Shortest pulse, middle of the cycle. bbits = 4'b0010; #200; abits = 4'b1000; // Longest cycle bbits = 4'b0001; #200; abits = 4'b1000; // Early in cycle, but not quite the longest. bbits = 4'b0010; #200; $finish; end // Reset initial begin reset = 0; #5 reset = 1; #100 reset = 0; end // Generate the 50MHz clock initial begin clk = 0; forever begin #10 clk = 1; #10 clk = 0; end end `define WAVES `ifdef WAVES initial begin $dumpfile ("wpulse.vcd"); $dumpvars (0,testwpulse); end `endif endmodule // synopsys translate_on [ [ [ 'module', 'wpulse', '(', [['reset'], ['clk'], ['abits'], ['bbits'], ['we']], ')', ';'], [ ['input', 'clk', ';'], ['input', 'reset', ';'], ['input', '[', '3', ':', '0', ']', 'abits', ';'], ['input', '[', '3', ':', '0', ']', 'bbits', ';'], ['output', 'we', ';'], ['reg', ['p1'], ['p2'], ';'], ['wire', ['adel1out'], ';'], ['wire', ['adel2out'], ';'], ['wire', ['adel3out'], ';'], ['wire', ['adel4out'], ';'], ['wire', ['bdel1out'], ';'], ['wire', ['bdel2out'], ';'], ['wire', ['bdel3out'], ';'], ['wire', ['bdel4out'], ';'], ['wire', ['adelout'], ';'], ['wire', ['bdelout'], ';'], [ 'always', ['@', '(', ['posedge', ['clk']], ')'], [ [ ['p1'], '<=', '(', [['reset']], ')', '|', '(', ['~', ['reset'], '&', '~', ['p1']], ')'], ';']], [ 'always', ['@', '(', ['posedge', ['clk']], ')'], [[['p2'], '<=', '(', ['~', ['reset'], '&', '~', ['p2']], ')'], ';']], [ 'delay4', [ ['adel1'], [ '(', ['.', 'a', '(', ['p1'], ')'], ['.', 'z', '(', ['adel1out'], ')'], ')']], ';'], [ 'delay4', [ ['adel2'], [ '(', ['.', 'a', '(', ['adel1out'], ')'], ['.', 'z', '(', ['adel2out'], ')'], ')']], ';'], [ 'delay4', [ ['adel3'], [ '(', ['.', 'a', '(', ['adel2out'], ')'], ['.', 'z', '(', ['adel3out'], ')'], ')']], ';'], [ 'delay4', [ ['adel4'], [ '(', ['.', 'a', '(', ['adel3out'], ')'], ['.', 'z', '(', ['adel4out'], ')'], ')']], ';'], [ 'delay4', [ ['bdel1'], [ '(', ['.', 'a', '(', ['p2'], ')'], ['.', 'z', '(', ['bdel1out'], ')'], ')']], ';'], [ 'delay4', [ ['bdel2'], [ '(', ['.', 'a', '(', ['bdel1out'], ')'], ['.', 'z', '(', ['bdel2out'], ')'], ')']], ';'], [ 'delay4', [ ['bdel3'], [ '(', ['.', 'a', '(', ['bdel2out'], ')'], ['.', 'z', '(', ['bdel3out'], ')'], ')']], ';'], [ 'delay4', [ ['bdel4'], [ '(', ['.', 'a', '(', ['bdel3out'], ')'], ['.', 'z', '(', ['bdel4out'], ')'], ')']], ';'], [ 'assign', [ ['adelout'], '=', ['abits', ['[', '3', ']']], '&', ['adel1out'], '|', ['abits', ['[', '2', ']']], '&', ['adel2out'], '|', ['abits', ['[', '1', ']']], '&', ['adel3out'], '|', ['abits', ['[', '0', ']']], '&', ['adel4out']], ';'], [ 'assign', [ ['bdelout'], '=', ['bbits', ['[', '3', ']']], '&', ['bdel1out'], '|', ['bbits', ['[', '2', ']']], '&', ['bdel2out'], '|', ['bbits', ['[', '1', ']']], '&', ['bdel3out'], '|', ['bbits', ['[', '0', ']']], '&', ['bdel4out']], ';'], ['assign', [['we'], '=', ['adelout'], '^', ['bdelout']], ';']], 'endmodule'], [ ['module', 'delay4', '(', [['a'], ['z']], ')', ';'], [ ['input', 'a', ';'], ['output', 'z', ';'], ['reg', ['z'], ';'], [ 'always', ['@', '(', [['a']], ')'], [[['z'], '=', ['#', '4'], ['a']], ';']]], 'endmodule'], [ ['module', 'testwpulse', ';'], [ ['reg', ['clk'], ';'], ['reg', ['reset'], ';'], ['reg', '[', '3', ':', '0', ']', ['abits'], ';'], ['reg', '[', '3', ':', '0', ']', ['bbits'], ';'], ['wire', ['we'], ';'], [ 'wpulse', [ ['wpulse_inst'], [ '(', ['.', 'reset', '(', ['reset'], ')'], ['.', 'clk', '(', ['clk'], ')'], ['.', 'abits', '(', ['abits'], ')'], ['.', 'bbits', '(', ['bbits'], ')'], ['.', 'we', '(', ['we'], ')'], ')']], ';'], [ 'initial', [ 'begin', [ [[['abits'], '=', "4 'b 1000"], ';'], [[['bbits'], '=', "4 'b 0100"], ';'], [['#', '200'], ';'], [[['abits'], '=', "4 'b 0010"], ';'], [[['bbits'], '=', "4 'b 0001"], ';'], [['#', '200'], ';'], [[['abits'], '=', "4 'b 0100"], ';'], [[['bbits'], '=', "4 'b 0010"], ';'], [['#', '200'], ';'], [[['abits'], '=', "4 'b 1000"], ';'], [[['bbits'], '=', "4 'b 0001"], ';'], [['#', '200'], ';'], [[['abits'], '=', "4 'b 1000"], ';'], [[['bbits'], '=', "4 'b 0010"], ';'], [['#', '200'], ';'], ['$finish', ';']], 'end']], [ 'initial', [ 'begin', [ [[['reset'], '=', '0'], ';'], [['#', '5'], [[['reset'], '=', '1'], ';']], [['#', '100'], [[['reset'], '=', '0'], ';']]], 'end']], [ 'initial', [ 'begin', [ [[['clk'], '=', '0'], ';'], [ 'forever', [ 'begin', [ [['#', '10'], [[['clk'], '=', '1'], ';']], [['#', '10'], [[['clk'], '=', '0'], ';']]], 'end']]], 'end']], [ 'initial', [ 'begin', [ ['$dumpfile', '(', '"wpulse.vcd"', ')', ';'], ['$dumpvars', '(', '0', ['testwpulse'], ')', ';']], 'end']]], 'endmodule']]