mcleod_ideafix

Knight Rider effect for FPGA

Oct 28th, 2020 (edited)
372
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //////////////////////////////////////////////////////////////////////////////////
  2. //    This file is knight_rider
  3. //    Creation date is 00:26:37 10/27/2020 by Miguel Angel Rodriguez Jodar
  4. //    (c)2020 Miguel Angel Rodriguez Jodar. ZXProjects
  5. //
  6. //    This core is free software: you can redistribute it and/or modify
  7. //    it under the terms of the GNU General Public License as published by
  8. //    the Free Software Foundation, either version 3 of the License, or
  9. //    (at your option) any later version.
  10. //
  11. //    This core is distributed in the hope that it will be useful,
  12. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. //    GNU General Public License for more details.
  15. //
  16. //    You should have received a copy of the GNU General Public License
  17. //    along with this core.  If not, see <https://www.gnu.org/licenses/>.
  18. //
  19. //    All copies of this file must keep this notice intact.
  20. //
  21. //////////////////////////////////////////////////////////////////////////////////
  22.  
  23. `timescale 1ns / 1ns
  24. `default_nettype none
  25.  
  26. module knight_rider (
  27.   input wire clk,
  28.   output wire [15:0] led
  29.   );  
  30.  
  31.   reg [26:0] count_per_shift = 'd0;
  32.   reg [26:0] count_per_fade  = 'd0;
  33.   reg [26:0] count_per_pwm   = 'd0;
  34.  
  35.   parameter [26:0] FREQ_CLK = 'd100_000_1000;  
  36.   parameter [26:0] FREQ_SHIFT = 'd10;
  37.   parameter [26:0] FREQ_FADEOUT = 'd100;
  38.   parameter [26:0] FREQ_PWM = 25 * FREQ_CLK / 128;
  39.  
  40.   localparam [26:0] PERIOD_SHIFT   = (FREQ_CLK / FREQ_SHIFT)-1;
  41.   localparam [26:0] PERIOD_FADEOUT = (FREQ_CLK / FREQ_FADEOUT)-1;
  42.   localparam [26:0] PERIOD_PWM     = (FREQ_CLK / FREQ_PWM)-1;
  43.  
  44.   always @(posedge clk) begin
  45.     if (count_per_shift == PERIOD_SHIFT)
  46.       count_per_shift <= 'd0;
  47.     else
  48.       count_per_shift <= count_per_shift + 'd1;
  49.      
  50.     if (count_per_fade == PERIOD_FADEOUT)
  51.       count_per_fade <= 'd0;
  52.     else
  53.       count_per_fade <= count_per_fade + 'd1;
  54.      
  55.     if (count_per_pwm == PERIOD_PWM)
  56.       count_per_pwm <= 'd0;
  57.     else
  58.       count_per_pwm <= count_per_pwm + 'd1;
  59.   end      
  60.    
  61.   wire enable_shift   = (count_per_shift == 'd0);
  62.   wire enable_fadeout = (count_per_fade == 'd0);
  63.   wire enable_pwm     = (count_per_pwm == 'd0);
  64.  
  65.   reg [15:0] estado_led = 16'b1000_0000_0000_0000;
  66.   reg sentido = 1'b0;  // 0=izq-der, 1=der-izq
  67.  
  68.   genvar i;
  69.   generate
  70.     for (i=0; i<=15; i=i+1) begin : controlador_led
  71.       ledpwm l (clk, enable_fadeout, enable_pwm, estado_led[i], led[i]);
  72.     end
  73.   endgenerate
  74.  
  75.   always @(posedge clk) begin
  76.     if (enable_shift == 1'b1) begin
  77.       if (sentido == 1'b0)
  78.         estado_led <= {1'b0, estado_led[15:1]};
  79.       else
  80.         estado_led <= {estado_led[14:0], 1'b0};
  81.       if (estado_led[14] == 1'b1 && sentido == 1'b1 || estado_led[1] == 1'b1 && sentido == 1'b0)
  82.           sentido <= ~sentido;
  83.     end
  84.   end
  85.  
  86. endmodule
  87.  
  88. module ledpwm (
  89.   input wire clk,
  90.   input wire clkefade,
  91.   input wire clkepwm,
  92.   input wire pulso_encendido,
  93.   output wire led
  94.   );
  95.  
  96.   reg [7:0] cnt = 'h00;
  97.   reg [7:0] brillo = 'h00;
  98.  
  99.   reg [7:0] lut[0:255];
  100.   reg [7:0] indxlut = 'd255;
  101.  
  102.   integer i;
  103.   localparam NUMERO_E = 2.7182818284590452353602874713527;
  104.   initial begin
  105.     for (i=0; i<256; i=i+1) begin
  106.       lut[i] = 255*(NUMERO_E ** (1-i/40.0))/NUMERO_E;
  107.     end
  108.   // Grafica de la función generada:
  109.   // http://fooplot.com/?lang=es#W3sidHlwZSI6MCwiZXEiOiJlXigxLXgvNDApKjI1NS9lIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMCIsIjI1NSIsIjAiLCIyNTUiXSwiZ3JpZCI6WyI1IiwiNSJdfV0-
  110.   end
  111.  
  112.   always @(posedge clk) begin
  113.     if (clkepwm == 1'b1)
  114.       cnt <= cnt + 'h01;
  115.   end
  116.  
  117.   always @(posedge clk) begin
  118.     brillo <= lut[indxlut];
  119.     if (pulso_encendido == 1'b1)
  120.       indxlut <= 'h00;
  121.     else if (clkefade == 1'b1 && indxlut != 'd255) begin
  122.        indxlut <= indxlut + 'h01;
  123.     end
  124.   end
  125.  
  126.   assign led = (brillo > cnt || brillo == 'hFF)? 1'b1: 1'b0;
  127. endmodule
  128.  
Add Comment
Please, Sign In to add comment