`timescale 1ns / 1ps `define DLY #1 ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 14:23:43 11/04/2011 // Design Name: // Module Name: altro_emulator // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module altro_emulator ( input rdoclk, input cstbn, input writen, output reg ackn, output reg trsfn, output dstbn, inout [39:0] bd, input reset ); parameter RAND_SAMPLES = 1; parameter NUM_SAMPLES = 1022; reg [9:0] num_samples; // Ammount of samples the emulator will send... per channel! reg [11:0] ch_addr; reg [9:0] trcfg; reg [19:0] altro_reg0; reg [19:0] altro_reg1; reg [39:0] bdout; reg bdout_en; reg dstbn_en; reg [3:0] clkcnt = 4'h0; assign dstbn = dstbn_en ? rdoclk : 1'b1; assign bd = bdout_en ? bdout : 40'hZ; parameter st0 = 0; parameter st1 = 1; parameter stc2 = 2; parameter stcw3 = 3; parameter stcw4 = 4; parameter stcr3 = 5; parameter stcr4 = 6; parameter stcr5 = 7; parameter strdo2 = 8; parameter strdo3 = 9; parameter strdo4 = 10; parameter strdo5 = 11; parameter strdo6 = 12; parameter strdo7 = 13; parameter strdo8 = 14; parameter strdo9 = 15; parameter strdo10 = 16; parameter stend = 20; reg [4:0] st; reg [9:0] samples_left; always @(posedge reset or posedge rdoclk) if(reset) begin trcfg <= /*`DLY*/ 10'h0; altro_reg0 <= /*`DLY*/ 20'h0; altro_reg1 <= /*`DLY*/ 20'h0; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ 12'h0; st <= /*`DLY*/ st0; end else case(st) st0 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ 12'h0; if(cstbn) st <= /*`DLY*/ st0; else st <= /*`DLY*/ st1; end st1 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ 12'h0; if(bd[24:20]==5'h1A) st <= /*`DLY*/ strdo2; else st <= /*`DLY*/ stc2; end stc2 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ 12'h0; if(writen) st <= /*`DLY*/ stcr3; else st <= /*`DLY*/ stcw3; end stcw3 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b0; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ 12'h0; case(bd[24:20]) 5'h0a : trcfg <= /*`DLY*/ bd[9:0]; 5'h01 : altro_reg0 <= /*`DLY*/ bd[19:0]; 5'h02 : altro_reg1 <= /*`DLY*/ bd[19:0]; default : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; end endcase st <= /*`DLY*/ stcw4; end stcw4 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b0; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ 12'h0; if(cstbn) st <= /*`DLY*/ st0; else st <= /*`DLY*/ stcw4; end stcr3 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout_en <= /*`DLY*/ 1'b1; ackn <= /*`DLY*/ 1'b0; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ 12'h0; case(bd[24:20]) 5'h0a : bdout <= /*`DLY*/ {30'h0,trcfg}; 5'h01 : bdout <= /*`DLY*/ {20'h0, altro_reg0}; 5'h02 : bdout <= /*`DLY*/ {20'h0, altro_reg1}; default : begin bdout <= /*`DLY*/ 40'h55005500; end endcase st <= /*`DLY*/ stcr4; end stcr4 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ bdout; bdout_en <= /*`DLY*/ 1'b1; ackn <= /*`DLY*/ 1'b0; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ 12'h0; st <= /*`DLY*/ stcr5; end stcr5 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ bdout; bdout_en <= /*`DLY*/ 1'b1; ackn <= /*`DLY*/ 1'b0; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ 12'h0; st <= /*`DLY*/ st0; end strdo2 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b0; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ bd[36:25]; st <= /*`DLY*/ strdo3; end strdo3 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b0; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ ch_addr; if(cstbn) st <= /*`DLY*/ strdo4; else st <= /*`DLY*/ strdo3; end strdo4 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ clkcnt + 4'h1; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ ch_addr; if(clkcnt == 4'd4) st <= /*`DLY*/ strdo5; else st <= /*`DLY*/ strdo4; end strdo5 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ ch_addr; st <= /*`DLY*/ strdo6; end strdo6 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ ch_addr; num_samples <= (RAND_SAMPLES)? $random % NUM_SAMPLES : NUM_SAMPLES; st <= /*`DLY*/ strdo7; end strdo7 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b0; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ ch_addr; st <= /*`DLY*/(num_samples < 10'd5)? strdo9 : strdo8; samples_left <= /*`DLY*/ num_samples; // $display("%m Number of samples %d", num_samples); end strdo8 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ {samples_left - 10'd3, samples_left - 10'd2, samples_left - 10'd1, samples_left}; bdout_en <= /*`DLY*/ 1'b1; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b0; dstbn_en <= /*`DLY*/ 1'b1; ch_addr <= /*`DLY*/ ch_addr; st <= (samples_left < 10'd9)? strdo9 : strdo8 ; samples_left <= /*`DLY*/ samples_left - 10'd4; end strdo9 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; case(samples_left) 10'd1: bdout <= /*`DLY*/ { 10'h2AA, 10'h2AA, 10'h2AA, samples_left}; 10'd2: bdout <= /*`DLY*/ { 10'h2AA, 10'h2AA, samples_left - 10'd1, samples_left }; 10'd3: bdout <= /*`DLY*/ { 10'h2AA, samples_left - 10'd2, samples_left - 10'd1, samples_left}; 10'd4: bdout <= /*`DLY*/ { samples_left - 10'd3, samples_left - 10'd2, samples_left - 10'd1, samples_left}; default: bdout <= /*`DLY*/ 40'hX; endcase bdout_en <= /*`DLY*/ 1'b1; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b0; dstbn_en <= /*`DLY*/ 1'b1; ch_addr <= /*`DLY*/ ch_addr; st <= strdo10 ; samples_left <= /*`DLY*/ samples_left - 4; end strdo10 : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; //bdout <= /*`DLY*/ {14'h2aaa,10'h11,4'ha,ch_addr}; //trailer bdout <= /*`DLY*/ {14'h2aaa, num_samples, 4'ha,ch_addr}; //trailer // 30 words. 28 samples, 1 timing info, 1 total samples. (assuming no zero suppresion is sent) //bdout <= /*`DLY*/ {14'h2aaa,10'h05,4'ha,ch_addr}; //trailer bdout_en <= /*`DLY*/ 1'b1; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b0; dstbn_en <= /*`DLY*/ 1'b1; ch_addr <= /*`DLY*/ ch_addr; st <= /*`DLY*/ stend; end // case: strdo10 stend : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ {40'hZ}; bdout_en <= /*`DLY*/ 1'b1; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b0; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ ch_addr; st <= /*`DLY*/ st0; end default : begin trcfg <= /*`DLY*/ trcfg; altro_reg0 <= /*`DLY*/ altro_reg0; altro_reg1 <= /*`DLY*/ altro_reg1; clkcnt <= /*`DLY*/ 4'h0; bdout <= /*`DLY*/ 40'h0; //trailer bdout_en <= /*`DLY*/ 1'b0; ackn <= /*`DLY*/ 1'b1; trsfn <= /*`DLY*/ 1'b1; dstbn_en <= /*`DLY*/ 1'b0; ch_addr <= /*`DLY*/ 12'h0; st <= /*`DLY*/ st0; samples_left <= samples_left; end endcase endmodule