| // It looks like for the models to be correctly annotated with timings from | |
| // SDF in Icarus Verilog the timescale provided here must match the one in SDF. | |
| // VPR writes SDFs in picoseconds hence here it is set to picoseconds as well. | |
| `timescale 1ps/1ps | |
| // VPR routing interconnect module | |
| module fpga_interconnect(datain, dataout); | |
| input datain; | |
| output dataout; | |
| // Behavioral model | |
| assign dataout = datain; | |
| // Timing paths. The values are dummy and are intended to be replaced by | |
| // ones from a SDF file during simulation. | |
| specify | |
| (datain => dataout) = 0; | |
| endspecify | |
| endmodule | |
| module frac_lut4_arith (in ,cin, lut4_out, cout); | |
| parameter [15:0] LUT = 16'd0; | |
| parameter [0: 0] MODE = 0; | |
| input [3:0] in; | |
| input [0:0] cin; | |
| output [0:0] lut4_out; | |
| output [0:0] cout; | |
| // Mode bits of frac_lut4_arith are responsible for the LI2 mux which | |
| // selects between the LI2 and CIN inputs. | |
| wire [3:0] li = (MODE == 1'b1) ? | |
| {in[3], cin, in[1], in[0]} : | |
| {in[3], in[2], in[1], in[0]}; | |
| // Output function | |
| wire [7:0] s1 = li[0] ? | |
| {LUT[14], LUT[12], LUT[10], LUT[8], LUT[6], LUT[4], LUT[2], LUT[0]} : | |
| {LUT[15], LUT[13], LUT[11], LUT[9], LUT[7], LUT[5], LUT[3], LUT[1]}; | |
| wire [3:0] s2 = li[1] ? | |
| {s1[6], s1[4], s1[2], s1[0]} : | |
| {s1[7], s1[5], s1[3], s1[1]}; | |
| wire [1:0] s3 = li[2] ? | |
| {s2[2], s2[0]} : | |
| {s2[3], s2[1]}; | |
| assign lut4_out = li[3] ? s3[0] : s3[1]; | |
| // Carry out function | |
| assign cout = s2[2] ? cin : s2[3]; | |
| // Timing paths. The values are dummy and are intended to be replaced by | |
| // ones from a SDF file during simulation. | |
| specify | |
| (cin => lut4_out) = 0; | |
| (cin => cout) = 0; | |
| endspecify | |
| endmodule | |
| module scff (D, DI, clk, reset, Q); // QL_IOFF | |
| parameter [0:0] MODE = 1; // The default | |
| input [0:0] D; | |
| input [0:0] DI; | |
| input [0:0] clk; | |
| input [0:0] reset; | |
| output [0:0] Q; | |
| scff_1 #(.MODE(MODE)) scff_1 ( | |
| .D (D), | |
| .DI (DI), | |
| .clk (clk), | |
| .preset (1'b1), | |
| .reset (reset), | |
| .Q (Q) | |
| ); | |
| endmodule | |
| module scff_1 (D, DI, clk, preset, reset, Q); // QL_FF | |
| parameter [0:0] MODE = 1; // The default | |
| input [0:0] D; | |
| input [0:0] DI; | |
| input [0:0] clk; | |
| input [0:0] preset; | |
| input [0:0] reset; | |
| output reg [0:0] Q; | |
| initial Q <= 1'b0; | |
| // Clock inverter | |
| wire ck = (MODE == 1'b1) ? clk : !clk; | |
| // FLip-flop behavioral model | |
| always @(posedge ck or negedge reset or negedge preset) begin | |
| if (!reset) Q <= 1'b0; | |
| else if (!preset) Q <= 1'b1; | |
| else Q <= D; | |
| end | |
| // Timing paths. The values are dummy and are intended to be replaced by | |
| // ones from a SDF file during simulation. | |
| specify | |
| (posedge clk => (Q +: D)) = 0; | |
| $setuphold(posedge clk, D, 0, 0); | |
| $recrem(posedge reset, posedge clk, 0, 0); | |
| $recrem(posedge preset, posedge clk, 0, 0); | |
| endspecify | |
| endmodule |