mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			794 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
			
		
		
	
	
			794 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
| `timescale 1ns/1ps
 | |
| 
 | |
| /*
 | |
|  This file contains simulation models for GreenPAK cells which are possible to fully model using synthesizeable
 | |
|  behavioral Verilog constructs only.
 | |
|  */
 | |
| 
 | |
| module GP_2LUT(input IN0, IN1, output OUT);
 | |
| 	parameter [3:0] INIT = 0;
 | |
| 	assign OUT = INIT[{IN1, IN0}];
 | |
| endmodule
 | |
| 
 | |
| module GP_3LUT(input IN0, IN1, IN2, output OUT);
 | |
| 	parameter [7:0] INIT = 0;
 | |
| 	assign OUT = INIT[{IN2, IN1, IN0}];
 | |
| endmodule
 | |
| 
 | |
| module GP_4LUT(
 | |
| 	input wire IN0,
 | |
| 	input wire IN1,
 | |
| 	input wire IN2,
 | |
| 	input wire IN3,
 | |
| 	output wire OUT);
 | |
| 
 | |
| 	parameter [15:0] INIT = 0;
 | |
| 	assign OUT = INIT[{IN3, IN2, IN1, IN0}];
 | |
| endmodule
 | |
| 
 | |
| module GP_CLKBUF(input wire IN, output wire OUT);
 | |
| 	assign OUT = IN;
 | |
| endmodule
 | |
| 
 | |
| module GP_COUNT14(input CLK, input wire RST, output reg OUT);
 | |
| 
 | |
| 	parameter RESET_MODE 	= "RISING";
 | |
| 
 | |
| 	parameter COUNT_TO		= 14'h1;
 | |
| 	parameter CLKIN_DIVIDE	= 1;
 | |
| 
 | |
| 	reg[13:0] count = COUNT_TO;
 | |
| 
 | |
| 	initial begin
 | |
| 		if(CLKIN_DIVIDE != 1) begin
 | |
| 			$display("ERROR: CLKIN_DIVIDE values other than 1 not implemented");
 | |
| 			$finish;
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	//Combinatorially output underflow flag whenever we wrap low
 | |
| 	always @(*) begin
 | |
| 		OUT = (count == 14'h0);
 | |
| 	end
 | |
| 
 | |
| 	//POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
 | |
| 	//Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
 | |
| 	generate
 | |
| 		case(RESET_MODE)
 | |
| 
 | |
| 			"RISING": begin
 | |
| 				always @(posedge CLK, posedge RST) begin
 | |
| 					if(RST)
 | |
| 						count		<= 0;
 | |
| 					else begin
 | |
| 						count		<= count - 1'd1;
 | |
| 						if(count == 0)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"FALLING": begin
 | |
| 				always @(posedge CLK, negedge RST) begin
 | |
| 					if(!RST)
 | |
| 						count		<= 0;
 | |
| 					else begin
 | |
| 						count		<= count - 1'd1;
 | |
| 						if(count == 0)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"BOTH": begin
 | |
| 				initial begin
 | |
| 					$display("Both-edge reset mode for GP_COUNT14 not implemented");
 | |
| 					$finish;
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"LEVEL": begin
 | |
| 				always @(posedge CLK, posedge RST) begin
 | |
| 					if(RST)
 | |
| 						count		<= 0;
 | |
| 
 | |
| 					else begin
 | |
| 						count		<= count - 1'd1;
 | |
| 						if(count == 0)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			default: begin
 | |
| 				initial begin
 | |
| 					$display("Invalid RESET_MODE on GP_COUNT14");
 | |
| 					$finish;
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 		endcase
 | |
| 	endgenerate
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| module GP_COUNT14_ADV(input CLK, input RST, output reg OUT,
 | |
|                      input UP, input KEEP, output reg[7:0] POUT);
 | |
| 
 | |
| 	parameter RESET_MODE 	= "RISING";
 | |
| 	parameter RESET_VALUE   = "ZERO";
 | |
| 
 | |
| 	parameter COUNT_TO		= 14'h1;
 | |
| 	parameter CLKIN_DIVIDE	= 1;
 | |
| 
 | |
| 	initial begin
 | |
| 		if(CLKIN_DIVIDE != 1) begin
 | |
| 			$display("ERROR: CLKIN_DIVIDE values other than 1 not implemented");
 | |
| 			$finish;
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	reg[13:0] count = COUNT_TO;
 | |
| 
 | |
| 	//Combinatorially output underflow flag whenever we wrap low
 | |
| 	always @(*) begin
 | |
| 		if(UP)
 | |
| 			OUT = (count == 14'h3fff);
 | |
| 		else
 | |
| 			OUT = (count == 14'h0);
 | |
| 		POUT = count[7:0];
 | |
| 	end
 | |
| 
 | |
| 	//POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
 | |
| 	//Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
 | |
| 	generate
 | |
| 		case(RESET_MODE)
 | |
| 
 | |
| 			"RISING": begin
 | |
| 				always @(posedge CLK, posedge RST) begin
 | |
| 
 | |
| 					//Resets
 | |
| 					if(RST) begin
 | |
| 						if(RESET_VALUE == "ZERO")
 | |
| 							count	<= 0;
 | |
| 						else
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 
 | |
| 					else if(KEEP) begin
 | |
| 					end
 | |
| 					else if(UP) begin
 | |
| 						count		<= count + 1'd1;
 | |
| 						if(count == 14'h3fff)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 					else begin
 | |
| 						count		<= count - 1'd1;
 | |
| 
 | |
| 						if(count == 0)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"FALLING": begin
 | |
| 				always @(posedge CLK, negedge RST) begin
 | |
| 
 | |
| 					//Resets
 | |
| 					if(!RST) begin
 | |
| 						if(RESET_VALUE == "ZERO")
 | |
| 							count	<= 0;
 | |
| 						else
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 
 | |
| 					else if(KEEP) begin
 | |
| 					end
 | |
| 					else if(UP) begin
 | |
| 						count		<= count + 1'd1;
 | |
| 						if(count == 14'h3fff)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 					else begin
 | |
| 						count		<= count - 1'd1;
 | |
| 
 | |
| 						if(count == 0)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"BOTH": begin
 | |
| 				initial begin
 | |
| 					$display("Both-edge reset mode for GP_COUNT14_ADV not implemented");
 | |
| 					$finish;
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"LEVEL": begin
 | |
| 				always @(posedge CLK, posedge RST) begin
 | |
| 
 | |
| 					//Resets
 | |
| 					if(RST) begin
 | |
| 						if(RESET_VALUE == "ZERO")
 | |
| 							count	<= 0;
 | |
| 						else
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 
 | |
| 					else begin
 | |
| 
 | |
| 						if(KEEP) begin
 | |
| 						end
 | |
| 						else if(UP) begin
 | |
| 							count		<= count + 1'd1;
 | |
| 							if(count == 14'h3fff)
 | |
| 								count	<= COUNT_TO;
 | |
| 						end
 | |
| 						else begin
 | |
| 							count		<= count - 1'd1;
 | |
| 
 | |
| 							if(count == 0)
 | |
| 								count	<= COUNT_TO;
 | |
| 						end
 | |
| 
 | |
| 					end
 | |
| 
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			default: begin
 | |
| 				initial begin
 | |
| 					$display("Invalid RESET_MODE on GP_COUNT14_ADV");
 | |
| 					$finish;
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 		endcase
 | |
| 	endgenerate
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| module GP_COUNT8_ADV(input CLK, input RST, output reg OUT,
 | |
|                      input UP, input KEEP, output reg[7:0] POUT);
 | |
| 
 | |
| 	parameter RESET_MODE 	= "RISING";
 | |
| 	parameter RESET_VALUE   = "ZERO";
 | |
| 
 | |
| 	parameter COUNT_TO		= 8'h1;
 | |
| 	parameter CLKIN_DIVIDE	= 1;
 | |
| 
 | |
| 	reg[7:0] count = COUNT_TO;
 | |
| 
 | |
| 	initial begin
 | |
| 		if(CLKIN_DIVIDE != 1) begin
 | |
| 			$display("ERROR: CLKIN_DIVIDE values other than 1 not implemented");
 | |
| 			$finish;
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	//Combinatorially output underflow flag whenever we wrap low
 | |
| 	always @(*) begin
 | |
| 		if(UP)
 | |
| 			OUT = (count == 8'hff);
 | |
| 		else
 | |
| 			OUT = (count == 8'h0);
 | |
| 		POUT = count;
 | |
| 	end
 | |
| 
 | |
| 	//POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
 | |
| 	//Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
 | |
| 	generate
 | |
| 		case(RESET_MODE)
 | |
| 
 | |
| 			"RISING": begin
 | |
| 				always @(posedge CLK, posedge RST) begin
 | |
| 
 | |
| 					//Resets
 | |
| 					if(RST) begin
 | |
| 						if(RESET_VALUE == "ZERO")
 | |
| 							count	<= 0;
 | |
| 						else
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 
 | |
| 					//Main counter
 | |
| 					else if(KEEP) begin
 | |
| 					end
 | |
| 					else if(UP) begin
 | |
| 						count		<= count + 1'd1;
 | |
| 						if(count == 8'hff)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 					else begin
 | |
| 						count		<= count - 1'd1;
 | |
| 
 | |
| 						if(count == 0)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"FALLING": begin
 | |
| 				always @(posedge CLK, negedge RST) begin
 | |
| 
 | |
| 					//Resets
 | |
| 					if(!RST) begin
 | |
| 						if(RESET_VALUE == "ZERO")
 | |
| 							count	<= 0;
 | |
| 						else
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 
 | |
| 					//Main counter
 | |
| 					else if(KEEP) begin
 | |
| 					end
 | |
| 					else if(UP) begin
 | |
| 						count		<= count + 1'd1;
 | |
| 						if(count == 8'hff)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 					else begin
 | |
| 						count		<= count - 1'd1;
 | |
| 
 | |
| 						if(count == 0)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"BOTH": begin
 | |
| 				initial begin
 | |
| 					$display("Both-edge reset mode for GP_COUNT8_ADV not implemented");
 | |
| 					$finish;
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"LEVEL": begin
 | |
| 				always @(posedge CLK, posedge RST) begin
 | |
| 
 | |
| 					//Resets
 | |
| 					if(RST) begin
 | |
| 						if(RESET_VALUE == "ZERO")
 | |
| 							count	<= 0;
 | |
| 						else
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 
 | |
| 					else begin
 | |
| 
 | |
| 						if(KEEP) begin
 | |
| 						end
 | |
| 						else if(UP) begin
 | |
| 							count		<= count + 1'd1;
 | |
| 							if(count == 8'hff)
 | |
| 								count	<= COUNT_TO;
 | |
| 						end
 | |
| 						else begin
 | |
| 							count		<= count - 1'd1;
 | |
| 
 | |
| 							if(count == 0)
 | |
| 								count	<= COUNT_TO;
 | |
| 						end
 | |
| 					end
 | |
| 
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			default: begin
 | |
| 				initial begin
 | |
| 					$display("Invalid RESET_MODE on GP_COUNT8_ADV");
 | |
| 					$finish;
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 		endcase
 | |
| 	endgenerate
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| module GP_COUNT8(
 | |
| 	input wire CLK,
 | |
| 	input wire RST,
 | |
| 	output reg OUT,
 | |
| 	output reg[7:0] POUT);
 | |
| 
 | |
| 	parameter RESET_MODE 	= "RISING";
 | |
| 
 | |
| 	parameter COUNT_TO		= 8'h1;
 | |
| 	parameter CLKIN_DIVIDE	= 1;
 | |
| 
 | |
| 	initial begin
 | |
| 		if(CLKIN_DIVIDE != 1) begin
 | |
| 			$display("ERROR: CLKIN_DIVIDE values other than 1 not implemented");
 | |
| 			$finish;
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	reg[7:0] count = COUNT_TO;
 | |
| 
 | |
| 	//Combinatorially output underflow flag whenever we wrap low
 | |
| 	always @(*) begin
 | |
| 		OUT = (count == 8'h0);
 | |
| 		POUT = count;
 | |
| 	end
 | |
| 
 | |
| 	//POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
 | |
| 	//Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
 | |
| 	generate
 | |
| 		case(RESET_MODE)
 | |
| 
 | |
| 			"RISING": begin
 | |
| 				always @(posedge CLK, posedge RST) begin
 | |
| 					if(RST)
 | |
| 						count	<= 0;
 | |
| 					else begin
 | |
| 						count		<= count - 1'd1;
 | |
| 						if(count == 0)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"FALLING": begin
 | |
| 				always @(posedge CLK, negedge RST) begin
 | |
| 					if(!RST)
 | |
| 						count	<= 0;
 | |
| 					else begin
 | |
| 						count		<= count - 1'd1;
 | |
| 						if(count == 0)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"BOTH": begin
 | |
| 				initial begin
 | |
| 					$display("Both-edge reset mode for GP_COUNT8 not implemented");
 | |
| 					$finish;
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			"LEVEL": begin
 | |
| 				always @(posedge CLK, posedge RST) begin
 | |
| 					if(RST)
 | |
| 						count	<= 0;
 | |
| 
 | |
| 					else begin
 | |
| 						count		<= count - 1'd1;
 | |
| 						if(count == 0)
 | |
| 							count	<= COUNT_TO;
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			default: begin
 | |
| 				initial begin
 | |
| 					$display("Invalid RESET_MODE on GP_COUNT8");
 | |
| 					$finish;
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 		endcase
 | |
| 	endgenerate
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| module GP_DCMPREF(output reg[7:0]OUT);
 | |
| 	parameter[7:0] REF_VAL = 8'h00;
 | |
| 	initial OUT = REF_VAL;
 | |
| endmodule
 | |
| 
 | |
| module GP_DCMPMUX(input[1:0] SEL, input[7:0] IN0, input[7:0] IN1, input[7:0] IN2, input[7:0] IN3, output reg[7:0] OUTA, output reg[7:0] OUTB);
 | |
| 
 | |
| 	always @(*) begin
 | |
| 		case(SEL)
 | |
| 			2'd00: begin
 | |
| 				OUTA = IN0;
 | |
| 				OUTB = IN3;
 | |
| 			end
 | |
| 
 | |
| 			2'd01: begin
 | |
| 				OUTA = IN1;
 | |
| 				OUTB = IN2;
 | |
| 			end
 | |
| 
 | |
| 			2'd02: begin
 | |
| 				OUTA = IN2;
 | |
| 				OUTB = IN1;
 | |
| 			end
 | |
| 
 | |
| 			2'd03: begin
 | |
| 				OUTA = IN3;
 | |
| 				OUTB = IN0;
 | |
| 			end
 | |
| 
 | |
| 		endcase
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DELAY(input IN, output reg OUT);
 | |
| 
 | |
| 	parameter DELAY_STEPS = 1;
 | |
| 	parameter GLITCH_FILTER = 0;
 | |
| 
 | |
| 	initial OUT = 0;
 | |
| 
 | |
| 	generate
 | |
| 
 | |
| 		if(GLITCH_FILTER) begin
 | |
| 			initial begin
 | |
| 				$display("ERROR: GP_DELAY glitch filter mode not implemented");
 | |
| 				$finish;
 | |
| 			end
 | |
| 		end
 | |
| 
 | |
| 		//TODO: These delays are PTV dependent! For now, hard code 3v3 timing
 | |
| 		//Change simulation-mode delay depending on global Vdd range (how to specify this?)
 | |
| 		always @(*) begin
 | |
| 			case(DELAY_STEPS)
 | |
| 				1: #166 OUT = IN;
 | |
| 				2: #318 OUT = IN;
 | |
| 				2: #471 OUT = IN;
 | |
| 				3: #622 OUT = IN;
 | |
| 				default: begin
 | |
| 					$display("ERROR: GP_DELAY must have DELAY_STEPS in range [1,4]");
 | |
| 					$finish;
 | |
| 				end
 | |
| 			endcase
 | |
| 		end
 | |
| 
 | |
| 	endgenerate
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| module GP_DFF(input D, CLK, output reg Q);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial Q = INIT;
 | |
| 	always @(posedge CLK) begin
 | |
| 		Q <= D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DFFI(input D, CLK, output reg nQ);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial nQ = INIT;
 | |
| 	always @(posedge CLK) begin
 | |
| 		nQ <= ~D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DFFR(input D, CLK, nRST, output reg Q);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial Q = INIT;
 | |
| 	always @(posedge CLK, negedge nRST) begin
 | |
| 		if (!nRST)
 | |
| 			Q <= 1'b0;
 | |
| 		else
 | |
| 			Q <= D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DFFRI(input D, CLK, nRST, output reg nQ);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial nQ = INIT;
 | |
| 	always @(posedge CLK, negedge nRST) begin
 | |
| 		if (!nRST)
 | |
| 			nQ <= 1'b1;
 | |
| 		else
 | |
| 			nQ <= ~D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DFFS(input D, CLK, nSET, output reg Q);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial Q = INIT;
 | |
| 	always @(posedge CLK, negedge nSET) begin
 | |
| 		if (!nSET)
 | |
| 			Q <= 1'b1;
 | |
| 		else
 | |
| 			Q <= D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DFFSI(input D, CLK, nSET, output reg nQ);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial nQ = INIT;
 | |
| 	always @(posedge CLK, negedge nSET) begin
 | |
| 		if (!nSET)
 | |
| 			nQ <= 1'b0;
 | |
| 		else
 | |
| 			nQ <= ~D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DFFSR(input D, CLK, nSR, output reg Q);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	parameter [0:0] SRMODE = 1'bx;
 | |
| 	initial Q = INIT;
 | |
| 	always @(posedge CLK, negedge nSR) begin
 | |
| 		if (!nSR)
 | |
| 			Q <= SRMODE;
 | |
| 		else
 | |
| 			Q <= D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DFFSRI(input D, CLK, nSR, output reg nQ);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	parameter [0:0] SRMODE = 1'bx;
 | |
| 	initial nQ = INIT;
 | |
| 	always @(posedge CLK, negedge nSR) begin
 | |
| 		if (!nSR)
 | |
| 			nQ <= ~SRMODE;
 | |
| 		else
 | |
| 			nQ <= ~D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DLATCH(input D, input nCLK, output reg Q);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial Q = INIT;
 | |
| 	always @(*) begin
 | |
| 		if(!nCLK)
 | |
| 			Q = D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DLATCHI(input D, input nCLK, output reg nQ);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial nQ = INIT;
 | |
| 	always @(*) begin
 | |
| 		if(!nCLK)
 | |
| 			nQ = ~D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DLATCHR(input D, input nCLK, input nRST, output reg Q);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial Q = INIT;
 | |
| 	always @(*) begin
 | |
| 		if(!nRST)
 | |
| 			Q = 1'b0;
 | |
| 		else if(!nCLK)
 | |
| 			Q = D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DLATCHRI(input D, input nCLK, input nRST, output reg nQ);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial nQ = INIT;
 | |
| 	always @(*) begin
 | |
| 		if(!nRST)
 | |
| 			nQ = 1'b1;
 | |
| 		else if(!nCLK)
 | |
| 			nQ = ~D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DLATCHS(input D, input nCLK, input nSET, output reg Q);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial Q = INIT;
 | |
| 	always @(*) begin
 | |
| 		if(!nSET)
 | |
| 			Q = 1'b1;
 | |
| 		else if(!nCLK)
 | |
| 			Q = D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DLATCHSI(input D, input nCLK, input nSET, output reg nQ);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	initial nQ = INIT;
 | |
| 	always @(*) begin
 | |
| 		if(!nSET)
 | |
| 			nQ = 1'b0;
 | |
| 		else if(!nCLK)
 | |
| 			nQ = ~D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DLATCHSR(input D, input nCLK, input nSR, output reg Q);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	parameter[0:0] SRMODE = 1'bx;
 | |
| 	initial Q = INIT;
 | |
| 	always @(*) begin
 | |
| 		if(!nSR)
 | |
| 			Q = SRMODE;
 | |
| 		else if(!nCLK)
 | |
| 			Q = D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_DLATCHSRI(input D, input nCLK, input nSR, output reg nQ);
 | |
| 	parameter [0:0] INIT = 1'bx;
 | |
| 	parameter[0:0] SRMODE = 1'bx;
 | |
| 	initial nQ = INIT;
 | |
| 	always @(*) begin
 | |
| 		if(!nSR)
 | |
| 			nQ = ~SRMODE;
 | |
| 		else if(!nCLK)
 | |
| 			nQ = ~D;
 | |
| 	end
 | |
| endmodule
 | |
| 
 | |
| module GP_IBUF(input IN, output OUT);
 | |
| 	assign OUT = IN;
 | |
| endmodule
 | |
| 
 | |
| module GP_IOBUF(input IN, input OE, output OUT, inout IO);
 | |
| 	assign OUT = IO;
 | |
| 	assign IO = OE ? IN : 1'bz;
 | |
| endmodule
 | |
| 
 | |
| module GP_INV(input IN, output OUT);
 | |
| 	assign OUT = ~IN;
 | |
| endmodule
 | |
| 
 | |
| module GP_OBUF(input IN, output OUT);
 | |
| 	assign OUT = IN;
 | |
| endmodule
 | |
| 
 | |
| module GP_OBUFT(input IN, input OE, output OUT);
 | |
| 	assign OUT = OE ? IN : 1'bz;
 | |
| endmodule
 | |
| 
 | |
| module GP_PGEN(input wire nRST, input wire CLK, output reg OUT);
 | |
| 	initial OUT = 0;
 | |
| 	parameter PATTERN_DATA = 16'h0;
 | |
| 	parameter PATTERN_LEN = 5'd16;
 | |
| 
 | |
| 	localparam COUNT_MAX =  PATTERN_LEN - 1'h1;
 | |
| 
 | |
| 	reg[3:0] count = 0;
 | |
| 	always @(posedge CLK, negedge nRST) begin
 | |
| 
 | |
| 		if(!nRST)
 | |
| 			count	<= 0;
 | |
| 
 | |
| 		else begin
 | |
| 			count	<= count - 1'h1;
 | |
| 			if(count == 0)
 | |
| 				count <= COUNT_MAX;
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	always @(*)
 | |
| 		OUT	= PATTERN_DATA[count];
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| module GP_SHREG(input nRST, input CLK, input IN, output OUTA, output OUTB);
 | |
| 
 | |
| 	parameter OUTA_TAP = 1;
 | |
| 	parameter OUTA_INVERT = 0;
 | |
| 	parameter OUTB_TAP = 1;
 | |
| 
 | |
| 	reg[15:0] shreg = 0;
 | |
| 
 | |
| 	always @(posedge CLK, negedge nRST) begin
 | |
| 
 | |
| 		if(!nRST)
 | |
| 			shreg = 0;
 | |
| 
 | |
| 		else
 | |
| 			shreg <= {shreg[14:0], IN};
 | |
| 
 | |
| 	end
 | |
| 
 | |
| 	assign OUTA = (OUTA_INVERT) ? ~shreg[OUTA_TAP - 1] : shreg[OUTA_TAP - 1];
 | |
| 	assign OUTB = shreg[OUTB_TAP - 1];
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| module GP_VDD(output OUT);
 | |
|        assign OUT = 1;
 | |
| endmodule
 | |
| 
 | |
| module GP_VSS(output OUT);
 | |
|        assign OUT = 0;
 | |
| endmodule
 |