// Code from LSU EE 4702-1 Spring 2000 Midterm

////////////////////////////////////////////////////////////////////////////////
//
// Problem 1 solution and demo.
//

module width_change(out,full,empty,outclk,in,inclk);
   input outclk, in, inclk;
   output out, full, empty;

   parameter storage = 20;

   wire [6:0] out;
   wire [2:0] in;
   wire       inclk, outclk, full, empty;
   
   reg [storage-1:0] sto;
   integer           amt;
   
   initial begin amt = 0; sto = 0; end

   assign full =  amt + 3 > storage;
   assign empty = amt === 0;
   assign out =   sto[6:0];

   always @( posedge outclk )
     if( amt >= 7 ) begin 
        sto = sto >> 7;
        amt = amt - 7;
     end

   always @( posedge inclk )
     if( !full ) begin
        sto = sto | in << amt;
        amt = amt + 3;
     end
   
endmodule // width_change

module wc_demo();

   wire [6:0] out;
   wire       full, empty;

   reg        outclk, inclk;
   reg [2:0]  in;

   width_change #(20) wc(out,full,empty,outclk,in,inclk);

   initial begin
      in = 0; outclk = 0; 
      fork
         forever begin inclk = 0; in = in + 1; #1; inclk = 1; #1; end
         #7 forever #3 outclk = ~outclk;
      join
   end

endmodule // wc_test

////////////////////////////////////////////////////////////////////////////////
//
// Problem 2b
//

// Code in exam.

module btos(x, a, b);
   input a, b;
   output x;
   wire   a, b;
   reg 	  x;
   
   always @( a or b ) if( a ) x = b; else x = ~b;

endmodule // btos

// Solution.

module explicit(x, a, b);
   input a, b;
   output x;
   wire   a, b;
   wire   x;                    // Wire, not reg.

   xnor (x,a,b);

endmodule


////////////////////////////////////////////////////////////////////////////////
//
// Problem 2c
//

// Code in exam.

module assig();
   reg [15:0] a, b;
   initial
     begin
	a = 1;
	b = 2;
	#1;
	a <= b;
	b <= a;
	#1;
	a <= b + 10;
	b <= #5 b + 20;
	#1;
	b = #1 3;
	b <= 4;
	b <= #2 5;
	b <= #10 6;
	b = 7;
        #20;
     end
endmodule


////////////////////////////////////////////////////////////////////////////////
//
// Problem 2d
//

// Code in exam.

module events1();

   wire a, b, c, d;
   reg  [3:0] x;

   reg [3:0] i;

   assign  {d,c,b,a} = i;
   
   initial
     begin
	i = 0;
        forever #10 i = i + 1;
     end

   always begin
      #15;
      @( a );
      x = 1;
      @( posedge a ) x = 2;
      @( a or b ) x = 3;
      @( a | b | c | d ) x = 4;
      wait( a | b ) x = 5;
      wait( a ) x = 6;
      wait( ~a ) x = 7;
   end // always begin

endmodule // events1

////////////////////////////////////////////////////////////////////////////////
//
// Problem 2e
//

// Code in exam.


module d();

   reg a;
   wire aa;
   
   and #(2,3) (aa,a,1);

   initial begin
      a = 0;
      # 10;
      a = 1;
      # 10;
      a = 0;
      # 10;
      a = 1;
      # 1;
      a = 0;
      # 10;
   end

endmodule // d


////////////////////////////////////////////////////////////////////////////////
//
// Problem 2f
//

// Code in exam.

module before(asum,bsum,out,a,ainp,b,binp,c);
   output asum, bsum, out;
   input  a, ainp, b, binp, c;

   reg [9:0]  asum, bsum, out;
   wire [9:0] ainp, binp;
   wire       a,b,c;

   always @( a ) asum = asum + ainp;

   always @( b ) bsum = bsum + binp;

   always @( posedge c ) out = asum + bsum;

endmodule 

// Solution

module after(asum,bsum,out,a,ainp,b,binp,c);
   output asum, bsum, out;
   input  a, ainp, b, binp, c;

   reg [9:0]  asum, bsum, out;
   wire [9:0] ainp, binp;
   wire       a,b,c;

   initial fork

      forever @( a ) asum = asum + ainp;
      forever @( b ) bsum = bsum + binp;
      forever @( posedge c ) out = asum + bsum;
      
   join
   
endmodule