Merge pull request #1862 from boqwxp/cleanup_techmap
[yosys.git] / techlibs / greenpak4 / cells_sim_digital.v
index cf80cece0fc463ef5b9c238fa83ec628ce9dc174..43d35d08f33c4c3c66ee49e585c756139de0bdf4 100644 (file)
@@ -15,7 +15,13 @@ module GP_3LUT(input IN0, IN1, IN2, output OUT);
        assign OUT = INIT[{IN2, IN1, IN0}];
 endmodule
 
-module GP_4LUT(input IN0, IN1, IN2, IN3, output OUT);
+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
@@ -24,6 +30,454 @@ 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;
@@ -288,40 +742,23 @@ module GP_PGEN(input wire nRST, input wire CLK, output reg OUT);
        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) begin
+       always @(posedge CLK, negedge nRST) begin
+
                if(!nRST)
-                       OUT <= PATTERN_DATA[0];
+                       count   <= 0;
 
                else begin
-                       count <= count + 1;
-                       OUT <= PATTERN_DATA[count];
-
-                       if( (count + 1) == PATTERN_LEN)
-                               count <= 0;
+                       count   <= count - 1'h1;
+                       if(count == 0)
+                               count <= COUNT_MAX;
                end
        end
 
-endmodule
-
-module GP_POR(output reg RST_DONE);
-       parameter POR_TIME = 500;
-
-       initial begin
-               RST_DONE = 0;
-
-               if(POR_TIME == 4)
-                       #4000;
-               else if(POR_TIME == 500)
-                       #500000;
-               else begin
-                       $display("ERROR: bad POR_TIME for GP_POR cell");
-                       $finish;
-               end
-
-               RST_DONE = 1;
-
-       end
+       always @(*)
+               OUT     = PATTERN_DATA[count];
 
 endmodule