Finished initial GP_COUNT8/14/8_ADV/14_ADV sim models. Don't support clock divide...
authorAndrew Zonenberg <azonenberg@drawersteak.com>
Tue, 8 Aug 2017 03:19:17 +0000 (20:19 -0700)
committerAndrew Zonenberg <azonenberg@drawersteak.com>
Mon, 14 Aug 2017 17:45:39 +0000 (10:45 -0700)
techlibs/greenpak4/cells_sim.v
techlibs/greenpak4/cells_sim_digital.v

index 13d7d19df56c1def2b0ba3eb01c6107ef9d155ef..2d7bed5cd188bcbbf51590d1a4aa07e08f4e025f 100644 (file)
@@ -5,43 +5,6 @@
 
 //Cells still in this file have INCOMPLETE simulation models, need to finish them
 
-module GP_COUNT14(input CLK, input wire RST, output reg OUT);
-
-       parameter RESET_MODE    = "RISING";
-
-       parameter COUNT_TO              = 14'h1;
-       parameter CLKIN_DIVIDE  = 1;
-
-       //more complex hard IP blocks are not supported for simulation yet
-
-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;
-
-       //more complex hard IP blocks are not supported for simulation yet
-
-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;
-
-       //more complex hard IP blocks are not supported for simulation yet
-
-endmodule
-
 module GP_DCMP(input[7:0] INP, input[7:0] INN, input CLK, input PWRDN, output reg GREATER, output reg EQUAL);
        parameter PWRDN_SYNC = 1'b0;
        parameter CLK_EDGE = "RISING";
index ccf9840c7b0408886e1f4b58e0206dd728378b35..0b83b7a2cf5dfce379e38513878db7b9d32e3821 100644 (file)
@@ -30,6 +30,292 @@ 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 or posedge RST) begin
+                                       count           <= count - 1'd1;
+                                       if(count == 0)
+                                               count   <= COUNT_TO;
+
+                                       if(RST)
+                                               count   <= 0;
+                               end
+                       end
+
+                       "FALLING": begin
+                               always @(posedge CLK or negedge RST) begin
+                                       count           <= count - 1'd1;
+                                       if(count == 0)
+                                               count   <= COUNT_TO;
+
+                                       if(!RST)
+                                               count   <= 0;
+                               end
+                       end
+
+                       "BOTH": begin
+                               initial begin
+                                       $display("Both-edge reset mode for GP_COUNT8 not implemented");
+                                       $finish;
+                               end
+                       end
+
+                       "LEVEL": begin
+                       end
+
+                       default: begin
+                               initial begin
+                                       $display("Invalid RESET_MODE on GP_COUNT8");
+                                       $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
+
+       //Combinatorially output underflow flag whenever we wrap low
+       always @(*) begin
+               if(UP)
+                       OUT <= (count == 14'h4000);
+               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 or posedge RST) begin
+
+                                       //Main counter
+                                       if(KEEP) begin
+                                       end
+                                       else if(UP)
+                                               count           <= count + 1'd1;
+                                       else
+                                               count           <= count - 1'd1;
+
+                                       //Wrapping
+                                       if(count == 0 && !UP)
+                                               count   <= COUNT_TO;
+                                       if(count == 14'h4000 && UP)
+                                               count   <= COUNT_TO;
+
+                                       //Resets
+                                       if(RST) begin
+                                               if(RESET_VALUE == "ZERO")
+                                                       count   <= 0;
+                                               else
+                                                       count   <= COUNT_TO;
+                                       end
+
+                               end
+                       end
+
+                       "FALLING": begin
+                               always @(posedge CLK or negedge RST) begin
+
+                                       //Main counter
+                                       if(KEEP) begin
+                                       end
+                                       else if(UP)
+                                               count           <= count + 1'd1;
+                                       else
+                                               count           <= count - 1'd1;
+
+                                       //Wrapping
+                                       if(count == 0 && !UP)
+                                               count   <= COUNT_TO;
+                                       if(count == 14'h4000 && UP)
+                                               count   <= COUNT_TO;
+
+                                       //Resets
+                                       if(RST) begin
+                                               if(RESET_VALUE == "ZERO")
+                                                       count   <= 0;
+                                               else
+                                                       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
+                       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;
+
+       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 or posedge RST) begin
+
+                                       //Main counter
+                                       if(KEEP) begin
+                                       end
+                                       else if(UP)
+                                               count           <= count + 1'd1;
+                                       else
+                                               count           <= count - 1'd1;
+
+                                       //Wrapping
+                                       if(count == 0 && !UP)
+                                               count   <= COUNT_TO;
+                                       if(count == 8'hff && UP)
+                                               count   <= COUNT_TO;
+
+                                       //Resets
+                                       if(RST) begin
+                                               if(RESET_VALUE == "ZERO")
+                                                       count   <= 0;
+                                               else
+                                                       count   <= COUNT_TO;
+                                       end
+
+                               end
+                       end
+
+                       "FALLING": begin
+                               always @(posedge CLK or negedge RST) begin
+
+                                       //Main counter
+                                       if(KEEP) begin
+                                       end
+                                       else if(UP)
+                                               count           <= count + 1'd1;
+                                       else
+                                               count           <= count - 1'd1;
+
+                                       //Wrapping
+                                       if(count == 0 && !UP)
+                                               count   <= COUNT_TO;
+                                       if(count == 8'hff && UP)
+                                               count   <= COUNT_TO;
+
+                                       //Resets
+                                       if(RST) begin
+                                               if(RESET_VALUE == "ZERO")
+                                                       count   <= 0;
+                                               else
+                                                       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
+                       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,
@@ -41,6 +327,13 @@ module GP_COUNT8(
        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