`timescale 1ns / 1ps
// Design: Multiplicador secuencial
// Description: Preifericos, y modulo top del diseño
// Author: Enrique Ostua <ostua@dte.us.es>, Paulino Ruiz de Clavijo Vázquez <paulino@dte.us.es>
// Copyright Universidad de Sevilla, Spain
// Rev: 1, mar 2011

/*
       1             Los segmentos son activos en bajo
      ---
   6 |   | 2
      ---   <- 7
   5 |   | 3
      ---
       4
*/

module sseg(
  input wire [3:0] d,
  output reg [7:1] seg
  );

  always @*
  begin
  case (d)
      4'h0: seg = 7'b1000000; //--0
      4'h1: seg = 7'b1111001; //--1
      4'h2: seg = 7'b0100100; //--2
      4'h3: seg = 7'b0110000; //--3
      4'h4: seg = 7'b0011001; //--4
      4'h5: seg = 7'b0010010; //--5
      4'h6: seg = 7'b0000010; //--6
      4'h7: seg = 7'b1111000; //--7
      4'h8: seg = 7'b0000000; //--8
      4'h9: seg = 7'b0010000; //--9
      4'hA: seg = 7'b0001000; //--A
      4'hB: seg = 7'b0000011; //--b
      4'hC: seg = 7'b1000110; //--C
      4'hD: seg = 7'b0100001; //--d
      4'hE: seg = 7'b0000110; //--E
      default: seg = 7'b0001110; //--F
    endcase
  end
endmodule  // sseg

// Modulo de refresco del display de 4 digitos 
// El reloj hay que conectarlo al de la placa
module display_controller(
  input  wire clk,               // Reloj para el refresco
  input  wire [3:0] d3,d2,d1,d0, // 4 digitos de entrada
  output wire [7:1] seg,         // Segmentos de salida
  output wire dp,                // Punto del segmentos
  output reg [3:0] an            // Anodos de los segmentos
   );

  reg [15:0] displcounter=0;   // Divisor de frecuencia
  reg [3:0] d;                 // Entrada BCD 
  
  assign dp = 1'b0; // Punto decimal: 0 ON, 1 OFF

  always @(posedge clk)
   begin
     displcounter = displcounter + 1;
   end
  
  always @(displcounter,d0,d1,d2,d3)
  begin
    case ({displcounter[15],displcounter[14]})
      2'b00:   begin d = d0; an = 4'b1110; end
      2'b01:   begin d = d1; an = 4'b1101; end
      2'b10:   begin d = d2; an = 4'b1011; end
      default:  begin d = d3; an = 4'b0111; end
    endcase
  end
  // Instancia del convertidor
   sseg U_bcdconverter(d, seg);
endmodule // display_controller


module sistema_completo(
  input wire clk,        // Reloj placa
  input wire clkext,     // Reloj boton
  input wire start,      // Generador de xs
  input wire reset,      // Reset de la unidad de control
  input wire [3:0] data, // Conectados directamente a los switches
  input wire [3:0] datb, // Conectados directamente a los switches
  output wire [6:0] seg, // Segmentos del displays
  output wire dp,        // Punto del display
  output wire [3:0] an,  // Anodos de los displays
  output reg[7:0] ld     // Leds
   );
  
  wire [7:0] busc; // Bus interno conectado a la unidad de datos
  reg xs=0;        // Señal para el comienzo
  wire fin;
  
  display_controller U_display(clk,
       data,  // Numero A conectado directamente desde los switches
       datb,  // Numero B conectado directamente desde los switches
       busc[7:4],busc[3:0], seg, dp, an);
  
    multiplicador U_multiplicador(
    .clk(clkext),
    .A(data),
    .B(datb),
    .xs(xs),
    .reset(reset),
    .fin(fin),
    .RESUL(busc));
    
  // Este proceso controla la señal xs a partir del pulsador
  always@(posedge start,posedge clkext)
  begin
     if(start)  
      xs <=1;   
     else
      xs <=0;
  end
  
  // Este proceso controla los leds.
  // Con la señal de fin se activan todos los leds
  always@(posedge clkext,posedge fin,posedge reset)
  begin
    if(reset)
      ld <= 8'b00000000;
    else if(fin)
      ld <= 8'b11111111;
    else if(xs)
      ld <= 8'b10000000;
    else
      ld <= {ld[0],ld[7:1]};  
  end
endmodule
