?? wpulse.v.txt
字號:
//
//
// 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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -