Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

all

  • Loading branch information...
commit 6373c97ba1fe95575558cdbe2cff05069bd4cc73 1 parent cab600f
kiarashplusplus authored
Showing with 16,083 additions and 0 deletions.
  1. +325 −0 moar code/AC97_PCM.v
  2. +102 −0 moar code/Binary_to_Decimal.coe
  3. +76 −0 moar code/Binary_to_Decimal.xco
  4. +95 −0 moar code/Button_Contention_Resolver.v
  5. +126 −0 moar code/Button_Contention_Resolver_tb.v
  6. +96 −0 moar code/CF_Interface_tb.v
  7. +1,959 −0 moar code/CF_Voicemail_Interface.v
  8. +3 −0  moar code/CLK_160.xaw
  9. +3 −0  moar code/CLK_40.xaw
  10. +1,380 −0 moar code/CRC_Dec_tb.v
  11. +131 −0 moar code/CRC_Enc_tb.v
  12. +82 −0 moar code/DEBUG_FIFO_1.xco
  13. +82 −0 moar code/DEBUG_FIFO_2.xco
  14. +2,323 −0 moar code/DLC.v
  15. +78 −0 moar code/DLC_ARQ_BRAM1.xco
  16. +82 −0 moar code/DLC_ARQ_FIFO1.xco
  17. +82 −0 moar code/DLC_ARQ_FIFO2.xco
  18. +78 −0 moar code/DLC_BRAM_RX.xco
  19. +78 −0 moar code/DLC_BRAM_TX.xco
  20. +82 −0 moar code/DLC_Request_FIFO.xco
  21. +380 −0 moar code/Date_Time.v
  22. +60 −0 moar code/LSFR_64.xco
  23. +82 −0 moar code/MAIN_FIFO.xco
  24. +82 −0 moar code/MAIN_FIFO2.xco
  25. +803 −0 moar code/PHY.v
  26. +62 −0 moar code/PHY_Decoder.xco
  27. +58 −0 moar code/PHY_Encoder.xco
  28. +82 −0 moar code/PHY_IN_FIFO.xco
  29. +82 −0 moar code/PHY_OUT_FIFO.xco
  30. +294 −0 moar code/PHY_Pair.v
  31. +222 −0 moar code/PHY_Pair_tb.v
  32. +82 −0 moar code/PHY_RX_FIFO_1.xco
  33. +94 −0 moar code/PHY_RX_Sample.v
  34. +120 −0 moar code/PHY_RX_Sample_tb.v
  35. +3 −0  moar code/Sample_Clock_Gen.xaw
  36. +207 −0 moar code/Text_Scroller.v
  37. +194 −0 moar code/Text_Scroller_tb.v
  38. +75 −0 moar code/UI_Text_Scroller_BRAM.xco
  39. +82 −0 moar code/Voicemail_FIFO.xco
  40. +170 −0 moar code/ZBT_Interface_tb.v
  41. +343 −0 moar code/display_string.v
  42. +446 −0 moar code/labkit_test1.v
  43. +812 −0 moar code/labkit_test2.v
  44. +627 −0 moar code/labkit_test3.v
  45. +684 −0 moar code/labkit_test4.v
  46. +1,008 −0 moar code/labkit_test5.v
  47. +831 −0 moar code/labkit_test6.v
  48. +742 −0 moar code/labkit_test7.v
  49. +93 −0 moar code/ramclock.v
View
325 moar code/AC97_PCM.v
@@ -0,0 +1,325 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company: 6.111
+// Engineer: Sachin Shinde
+//
+// Create Date: 03:07:52 10/31/2012
+// Design Name: AC97-PCM Interface
+// Module Name: AC97_PCM
+// Project Name: 6.111 Final Project
+// Target Devices: Xilinx XC2V6000
+// Tool versions:
+// Description: An interface between the LM4550 AC '97 Audio Codec and the
+// 48kHz PCM data stream that:
+// 1) Assembles PCM audio output into LM4550 sdata_out frames
+// 2) Disassembles LM4550 sdata_in frames into PCM audio input
+// 3) Manages all LM4550 control signals (including headphone
+// volume)
+//
+// Ready (a one-clock pulse) times I/O of the PCM stream. On the
+// rising edge of ready, audio input is avaiable. On the falling
+// edge of ready, audio output is latched.
+//
+// The PCM stream bit depth is 16 and sampling rate is 8kHz.
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+// Audio input will be held for at least 128 AC97 bit clocks
+// (around 280 27MHz clocks w/ AC97 bit clock @ 12.288MHz).
+//
+//////////////////////////////////////////////////////////////////////////////////
+module AC97_PCM(
+ input wire clock_27mhz,
+ input wire reset,
+ input wire [4:0] volume,
+ // PCM interface signals
+ output wire [15:0] audio_in_data,
+ input wire [15:0] audio_out_data,
+ output wire ready,
+ // LM4550 interface signals
+ output reg audio_reset_b,
+ output wire ac97_sdata_out,
+ input wire ac97_sdata_in,
+ output wire ac97_synch,
+ input wire ac97_bit_clock
+ );
+
+ wire [7:0] command_address;
+ wire [15:0] command_data;
+ wire command_valid;
+ wire [19:0] left_in_data, right_in_data;
+ wire [19:0] left_out_data, right_out_data;
+
+ // Wait 1024 clock cycles before enabling the LM4550
+ reg [9:0] reset_count;
+ always @(posedge clock_27mhz) begin
+ if (reset) begin
+ audio_reset_b = 1'b0;
+ reset_count = 0;
+ end
+ else if (reset_count == 1023)
+ audio_reset_b = 1'b1;
+ else
+ reset_count = reset_count+1;
+ end
+
+ // Assemble/Disassemble serial frames for LM4550
+ wire ac97_ready;
+ wire slot_req; // slot request for Variable Rate Audio (VRA)
+ ac97 ac97(.ready(ac97_ready),
+ .command_address(command_address),
+ .command_data(command_data),
+ .command_valid(command_valid),
+ .left_data(left_out_data), .left_valid(1'b1),
+ .right_data(right_out_data), .right_valid(1'b1),
+ .left_in_data(left_in_data), .right_in_data(right_in_data),
+ .slot_req(slot_req),
+ .ac97_sdata_out(ac97_sdata_out),
+ .ac97_sdata_in(ac97_sdata_in),
+ .ac97_synch(ac97_synch),
+ .ac97_bit_clock(ac97_bit_clock));
+
+ // Generate int_ready (one-clock pulse, synchronous with clock_27mhz)
+ // from ac97_ready (long pulse, synchronouse with ac97_bit_clock)
+ reg [2:0] ready_sync;
+ wire int_ready;
+ always @ (posedge clock_27mhz)
+ ready_sync <= {ready_sync[1:0], ac97_ready};
+ assign int_ready = ready_sync[1] & ~ready_sync[2];
+
+ // Generate ready signal taking into account LM4550 slot requests
+ assign ready = int_ready & slot_req;
+
+ // Latch audio output on falling edge of ready
+ reg [15:0] out_data;
+ always @ (posedge clock_27mhz)
+ if (ready) out_data <= audio_out_data;
+
+ // Assign audio input (16 bits)
+ assign audio_in_data = left_in_data[19:4];
+
+ // Assign LM4550 L/R output data signals
+ assign left_out_data = {out_data, 4'h0};
+ assign right_out_data = left_out_data;
+
+ // Generate R/W control signals for LM4550
+ ac97commands cmds(.clock(clock_27mhz), .ready(int_ready),
+ .command_address(command_address),
+ .command_data(command_data),
+ .command_valid(command_valid),
+ .volume(volume),
+ .source(3'b000)); // mic
+endmodule
+
+// Assemble/Disassemble serial frames for LM4550
+module ac97 (
+ output reg ready,
+ // Commmand signals
+ input wire [7:0] command_address,
+ input wire [15:0] command_data,
+ input wire command_valid,
+ // L/R data output signals
+ input wire [19:0] left_data, right_data,
+ input wire left_valid, right_valid,
+ // L/R data input signals
+ output reg [19:0] left_in_data, right_in_data,
+ output reg slot_req,
+ // LM4550 Serial Interface signals
+ output reg ac97_sdata_out,
+ input wire ac97_sdata_in,
+ output reg ac97_synch,
+ input wire ac97_bit_clock
+ );
+
+ // Counter for bit position in frame
+ reg [7:0] bit_count;
+
+ // Latched output signals
+ reg [19:0] l_cmd_addr;
+ reg [19:0] l_cmd_data;
+ reg [19:0] l_left_data, l_right_data;
+ reg l_cmd_v, l_left_v, l_right_v;
+
+ initial begin
+ ready <= 1'b0;
+ // synthesis attribute init of ready is "0";
+ ac97_sdata_out <= 1'b0;
+ // synthesis attribute init of ac97_sdata_out is "0";
+ ac97_synch <= 1'b0;
+ // synthesis attribute init of ac97_synch is "0";
+
+ bit_count <= 8'h00;
+ // synthesis attribute init of bit_count is "0000";
+ l_cmd_v <= 1'b0;
+ // synthesis attribute init of l_cmd_v is "0";
+ l_left_v <= 1'b0;
+ // synthesis attribute init of l_left_v is "0";
+ l_right_v <= 1'b0;
+ // synthesis attribute init of l_right_v is "0";
+
+ left_in_data <= 20'h00000;
+ // synthesis attribute init of left_in_data is "00000";
+ right_in_data <= 20'h00000;
+ // synthesis attribute init of right_in_data is "00000";
+
+ slot_req <= 1'b0;
+ // synthesis attribute init of right_in_data is "0";
+ end
+
+ // Generate basic signals
+ always @(posedge ac97_bit_clock) begin
+ // Generate the sync signal
+ if (bit_count == 255)
+ ac97_synch <= 1'b1;
+ if (bit_count == 15)
+ ac97_synch <= 1'b0;
+
+ // Generate the ready signal (synchronous with ac97_bit_clock)
+ if (bit_count == 128)
+ ready <= 1'b1;
+ if (bit_count == 2)
+ ready <= 1'b0;
+
+ // Update bit_count
+ bit_count <= bit_count+1;
+ end
+
+ // Generate ac97_sdata_out from latched audio output
+ always @(posedge ac97_bit_clock) begin
+ if ((bit_count >= 0) && (bit_count <= 15)) begin
+ // Slot 0: Tags
+ case (bit_count[3:0])
+ 4'h0: ac97_sdata_out <= 1'b1; // Frame valid
+ 4'h1: ac97_sdata_out <= l_cmd_v; // Command address valid
+ 4'h2: ac97_sdata_out <= l_cmd_v; // Command data valid
+ 4'h3: ac97_sdata_out <= l_left_v; // Left data valid
+ 4'h4: ac97_sdata_out <= l_right_v; // Right data valid
+ default: ac97_sdata_out <= 1'b0;
+ endcase
+ end
+ else if ((bit_count >= 16) && (bit_count <= 35))
+ // Slot 1: Command address (8-bits, left justified)
+ ac97_sdata_out <= l_cmd_v ? l_cmd_addr[35-bit_count] : 1'b0;
+ else if ((bit_count >= 36) && (bit_count <= 55))
+ // Slot 2: Command data (16-bits, left justified)
+ ac97_sdata_out <= l_cmd_v ? l_cmd_data[55-bit_count] : 1'b0;
+ else if ((bit_count >= 56) && (bit_count <= 75)) begin
+ // Slot 3: Left channel
+ ac97_sdata_out <= l_left_v ? l_left_data[19] : 1'b0;
+ l_left_data <= { l_left_data[18:0], l_left_data[19] };
+ end
+ else if ((bit_count >= 76) && (bit_count <= 95))
+ // Slot 4: Right channel
+ ac97_sdata_out <= l_right_v ? l_right_data[95-bit_count] : 1'b0;
+ // Latch output signals at the end of each frame. This ensures that
+ // the first frame after reset will be empty.
+ else if (bit_count == 255) begin
+ l_cmd_addr <= {command_address, 12'h000};
+ l_cmd_data <= {command_data, 4'h0};
+ l_cmd_v <= command_valid;
+ l_left_data <= left_data;
+ l_left_v <= left_valid;
+ l_right_data <= right_data;
+ l_right_v <= right_valid;
+ ac97_sdata_out <= 1'b0;
+ end
+ else
+ ac97_sdata_out <= 1'b0;
+ end
+
+ // Extract audio input from ac97_sdata_in
+ always @(negedge ac97_bit_clock) begin
+ if ((bit_count >= 57) && (bit_count <= 76))
+ // Slot 3: Left channel
+ left_in_data <= { left_in_data[18:0], ac97_sdata_in };
+ else if ((bit_count >= 77) && (bit_count <= 96))
+ // Slot 4: Right channel
+ right_in_data <= { right_in_data[18:0], ac97_sdata_in };
+ end
+
+ // Extract slot request bit for Variable Rate Audio (VRA)
+ always @(negedge ac97_bit_clock) begin
+ if (bit_count == 25)
+ slot_req <= ~ac97_sdata_in;
+ end
+endmodule
+
+// Generate R/W control signals for LM4550
+module ac97commands (
+ input wire clock,
+ input wire ready,
+ // Command signals
+ output wire [7:0] command_address,
+ output wire [15:0] command_data,
+ output reg command_valid,
+ // Other signals
+ input wire [4:0] volume,
+ input wire [2:0] source
+ );
+
+ // Create command register & state
+ reg [23:0] command;
+ reg [3:0] state;
+
+ // Assign command signal outputs
+ assign command_address = command[23:16];
+ assign command_data = command[15:0];
+
+ initial begin
+ command <= 24'h00_0000;
+ // synthesis attribute init of command is "00_0000";
+ command_valid <= 1'b0;
+ // synthesis attribute init of command_valid is "0";
+ state <= 4'h0;
+ // synthesis attribute init of state is "0";
+ end
+
+ // Convert volume to attentuation
+ wire [4:0] vol;
+ assign vol = 5'd31 - volume;
+
+ // Update state and command vars
+ always @(posedge clock) begin
+ // Increment state
+ if (ready) state <= state+1;
+
+ // Set command
+ case (state)
+ 4'h0: begin // Read reset register (7'h00)
+ command <= 24'h80_0000;
+ command_valid <= 1'b1;
+ end
+ 4'h1: // Read reset register (7'h00)
+ command <= 24'h80_0000;
+ 4'h2: // Set Variable Rate Audio (7'h2A) LSB to 1
+ command <= 24'h2A_0001;
+ 4'h3: // Set PCM DAC Sampling rate (7'h2C) to 8kHz
+ command <= 24'h2C_1F40;
+ 4'h4: // Set PCM ADC Sampling rate (7'h32) to 8kHz
+ command <= 24'h32_1F40;
+ 4'h5: // Set headphone volume (7'h04) on both L/R to vol
+ command <= { 8'h04, 3'b000, vol, 3'b000, vol };
+ 4'h6: // Set PCM output volume (7'h18) on both L/R to 6dB gain
+ command <= 24'h18_0808;
+ 4'h7: // Set record select (7'h1A) to source (mic)
+ command <= { 8'h1A, 5'b00000, source, 5'b00000, source};
+ 4'h8: // Set record gain (7'h1C) to max (22.5dB gain)
+ command <= 24'h1C_0F0F;
+ 4'h9: // Set mic volume (7'h0E) bit 6 for 20dB boost amplifier
+ command <= 24'h0E_8048;
+ 4'hA: // Set PC beep volume (7'h0A) to 0dB attentuation
+ command <= 24'h0A_0000;
+ 4'hB: // Set general purpose register (7'h20) so that:
+ // * PCM output bypasses 3D circuitry
+ // * National 3D Sound is off
+ // * mic1 is selected
+ // * No ADC/DAC loopback
+ command <= 24'h20_8000;
+ default:
+ command <= 24'h80_0000;
+ endcase
+ end
+endmodule
View
102 moar code/Binary_to_Decimal.coe
@@ -0,0 +1,102 @@
+memory_initialization_radix=16;
+memory_initialization_vector=
+00,
+01,
+02,
+03,
+04,
+05,
+06,
+07,
+08,
+09,
+10,
+11,
+12,
+13,
+14,
+15,
+16,
+17,
+18,
+19,
+20,
+21,
+22,
+23,
+24,
+25,
+26,
+27,
+28,
+29,
+30,
+31,
+32,
+33,
+34,
+35,
+36,
+37,
+38,
+39,
+40,
+41,
+42,
+43,
+44,
+45,
+46,
+47,
+48,
+49,
+50,
+51,
+52,
+53,
+54,
+55,
+56,
+57,
+58,
+59,
+60,
+61,
+62,
+63,
+64,
+65,
+66,
+67,
+68,
+69,
+70,
+71,
+72,
+73,
+74,
+75,
+76,
+77,
+78,
+79,
+80,
+81,
+82,
+83,
+84,
+85,
+86,
+87,
+88,
+89,
+90,
+91,
+92,
+93,
+94,
+95,
+96,
+97,
+98,
+99;
View
76 moar code/Binary_to_Decimal.xco
@@ -0,0 +1,76 @@
+##############################################################
+#
+# Xilinx Core Generator version K.39
+# Date: Sun Nov 25 07:51:57 2012
+#
+##############################################################
+#
+# This file contains the customisation parameters for a
+# Xilinx CORE Generator IP GUI. It is strongly recommended
+# that you do not manually alter this file as it may cause
+# unexpected and unsupported behavior.
+#
+##############################################################
+#
+# BEGIN Project Options
+SET addpads = False
+SET asysymbol = True
+SET busformat = BusFormatAngleBracketNotRipped
+SET createndf = False
+SET designentry = VHDL
+SET device = xc2v6000
+SET devicefamily = virtex2
+SET flowvendor = Foundation_iSE
+SET formalverification = False
+SET foundationsym = False
+SET implementationfiletype = Ngc
+SET package = bf957
+SET removerpms = False
+SET simulationfiles = Behavioral
+SET speedgrade = -4
+SET verilogsim = True
+SET vhdlsim = True
+# END Project Options
+# BEGIN Select
+SELECT Dual_Port_Block_Memory family Xilinx,_Inc. 6.3
+# END Select
+# BEGIN Parameters
+CSET coefficient_file="C:\Users\Sachin Shinde\Desktop\6.111\Final Project\Verilog\Final_Project\Binary_to_Decimal.coe"
+CSET component_name=Binary_to_Decimal
+CSET configuration_port_a=Read_Only
+CSET configuration_port_b=Read_Only
+CSET depth_a=100
+CSET depth_b=100
+CSET disable_warning_messages=true
+CSET global_init_value=0
+CSET load_init_file=true
+CSET port_a_active_clock_edge=Rising_Edge_Triggered
+CSET port_a_additional_output_pipe_stages=0
+CSET port_a_enable_pin=false
+CSET port_a_enable_pin_polarity=Active_High
+CSET port_a_handshaking_pins=false
+CSET port_a_init_pin=false
+CSET port_a_init_value=0
+CSET port_a_initialization_pin_polarity=Active_High
+CSET port_a_register_inputs=false
+CSET port_a_write_enable_polarity=Active_High
+CSET port_b_active_clock_edge=Rising_Edge_Triggered
+CSET port_b_additional_output_pipe_stages=0
+CSET port_b_enable_pin=false
+CSET port_b_enable_pin_polarity=Active_High
+CSET port_b_handshaking_pins=false
+CSET port_b_init_pin=false
+CSET port_b_init_value=0
+CSET port_b_initialization_pin_polarity=Active_High
+CSET port_b_register_inputs=false
+CSET port_b_write_enable_polarity=Active_High
+CSET primitive_selection=Optimize_For_Area
+CSET select_primitive=16kx1
+CSET width_a=8
+CSET width_b=8
+CSET write_mode_port_a=Read_After_Write
+CSET write_mode_port_b=Read_After_Write
+# END Parameters
+GENERATE
+# CRC: eb737bc0
+
View
95 moar code/Button_Contention_Resolver.v
@@ -0,0 +1,95 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer: Sachin Shinde
+//
+// Create Date: 04:08:44 11/22/2012
+// Design Name:
+// Module Name: Button_Contention_Resolver
+// Project Name:
+// Target Devices:
+// Tool versions:
+// Description: Takes debounced button inputs, and manages button contention
+// such that only one button signal is high per clock. There is
+// also guaranteed to be at least one cycle of no button presses
+// between consecutive button presses. This is useful for
+// generically determining when a button is released, as it
+// becomes the bitwise-or of the button signals.
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+module Button_Contention_Resolver(
+ input clk,
+ input reset,
+ // Button Inputs
+ input button0_in,
+ input button1_in,
+ input button2_in,
+ input button3_in,
+ input button_enter_in,
+ input button_left_in,
+ input button_right_in,
+ input button_up_in,
+ input button_down_in,
+ // Button Outputs
+ output button0_out,
+ output button1_out,
+ output button2_out,
+ output button3_out,
+ output button_enter_out,
+ output button_left_out,
+ output button_right_out,
+ output button_up_out,
+ output button_down_out
+ );
+
+ // Instantiate state var
+ reg state;
+
+ // Define state parameters
+ parameter S_RESET = 0;
+ parameter S_SET = 1;
+
+ // Assign input
+ wire [8:0] button_in;
+ assign button_in =
+ {button0_in, button1_in, button2_in, button3_in, button_enter_in,
+ button_left_in, button_right_in, button_up_in, button_down_in};
+
+ // Assign output
+ reg [8:0] button_out;
+ assign {button0_out, button1_out, button2_out, button3_out, button_enter_out,
+ button_left_out, button_right_out, button_up_out, button_down_out}
+ = button_out;
+
+ // Manage state transitions and output
+ wire [8:0] button_in_minus_one;
+ assign button_in_minus_one = button_in - 1;
+ always @(posedge clk) begin
+ if (reset) begin
+ state <= S_RESET;
+ button_out <= 9'd0;
+ end
+ else begin
+ case (state)
+ S_RESET: begin
+ if ((|button_in) & !(button_in_minus_one & button_in)) begin
+ state <= S_SET;
+ button_out <= button_in;
+ end
+ end
+ S_SET: begin
+ if (!(button_out & button_in)) begin
+ state <= S_RESET;
+ button_out <= 9'd0;
+ end
+ end
+ endcase
+ end
+ end
+endmodule
View
126 moar code/Button_Contention_Resolver_tb.v
@@ -0,0 +1,126 @@
+`timescale 1ns / 1ps
+
+////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 05:33:41 11/22/2012
+// Design Name: Button_Contention_Resolver
+// Module Name: C:/Users/Sachin Shinde/Desktop/6.111/Final Project/Verilog/Final_Project/Button_Contention_Resolver_tb.v
+// Project Name: Final_Project
+// Target Device:
+// Tool versions:
+// Description:
+//
+// Verilog Test Fixture created by ISE for module: Button_Contention_Resolver
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+////////////////////////////////////////////////////////////////////////////////
+
+module Button_Contention_Resolver_tb;
+
+ // Inputs
+ reg clk;
+ reg reset;
+ reg button0_in;
+ reg button1_in;
+ reg button2_in;
+ reg button3_in;
+ reg button_enter_in;
+ reg button_left_in;
+ reg button_right_in;
+ reg button_up_in;
+ reg button_down_in;
+
+ // Outputs
+ wire button0_out;
+ wire button1_out;
+ wire button2_out;
+ wire button3_out;
+ wire button_enter_out;
+ wire button_left_out;
+ wire button_right_out;
+ wire button_up_out;
+ wire button_down_out;
+
+ // Instantiate the Unit Under Test (UUT)
+ Button_Contention_Resolver uut (
+ .clk(clk),
+ .reset(reset),
+ .button0_in(button0_in),
+ .button1_in(button1_in),
+ .button2_in(button2_in),
+ .button3_in(button3_in),
+ .button_enter_in(button_enter_in),
+ .button_left_in(button_left_in),
+ .button_right_in(button_right_in),
+ .button_up_in(button_up_in),
+ .button_down_in(button_down_in),
+ .button0_out(button0_out),
+ .button1_out(button1_out),
+ .button2_out(button2_out),
+ .button3_out(button3_out),
+ .button_enter_out(button_enter_out),
+ .button_left_out(button_left_out),
+ .button_right_out(button_right_out),
+ .button_up_out(button_up_out),
+ .button_down_out(button_down_out)
+ );
+
+ // Create 100MHz clock
+ always #5 clk = ~clk;
+
+ initial begin
+ // Initialize Inputs
+ clk = 0;
+ reset = 1;
+ button0_in = 0;
+ button1_in = 0;
+ button2_in = 0;
+ button3_in = 0;
+ button_enter_in = 0;
+ button_left_in = 0;
+ button_right_in = 0;
+ button_up_in = 0;
+ button_down_in = 0;
+
+ // Wait 100 ns for global reset to finish
+ #100;
+
+ // Add stimulus here
+ @(posedge clk)
+ reset <= 0;
+ button0_in <= 1;
+ @(posedge clk)
+ button1_in <= 1;
+ @(posedge clk)
+ button2_in <= 1;
+ @(posedge clk)
+ button3_in <= 1;
+ @(posedge clk)
+ button0_in <= 0;
+ @(posedge clk)
+ button1_in <= 0;
+ @(posedge clk)
+ button2_in <= 0;
+ @(posedge clk)
+ button3_in <= 0;
+ button0_in <= 1;
+ @(posedge clk)
+ button0_in <= 0;
+ button1_in <= 1;
+ @(posedge clk)
+ button1_in <= 0;
+ button2_in <= 1;
+ @(posedge clk)
+ button2_in <= 0;
+ button3_in <= 1;
+ end
+
+endmodule
+
View
96 moar code/CF_Interface_tb.v
@@ -0,0 +1,96 @@
+`timescale 1ns / 1ps
+
+////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 18:28:35 11/24/2012
+// Design Name: CF_Interface
+// Module Name: C:/Users/Sachin Shinde/Desktop/6.111/Final Project/Verilog/Final_Project/CF_Interface_tb.v
+// Project Name: Final_Project
+// Target Device:
+// Tool versions:
+// Description:
+//
+// Verilog Test Fixture created by ISE for module: CF_Interface
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+////////////////////////////////////////////////////////////////////////////////
+
+module CF_Interface_tb;
+
+ // Inputs
+ reg clk_27mhz;
+ reg reset;
+ reg [1:0] cmd;
+ reg [27:0] LBA;
+ reg [7:0] SC;
+ reg [15:0] din;
+ reg systemace_mpbrdy;
+
+ // Outputs
+ wire we_req;
+ wire [15:0] dout;
+ wire nd;
+ wire CF_detect;
+ wire [27:0] LBA_max;
+ wire ready;
+ wire [6:0] systemace_address;
+ wire systemace_ce_b;
+ wire systemace_we_b;
+ wire systemace_oe_b;
+
+ // Bidirs
+ wire [15:0] systemace_data;
+ reg [15:0] systemace_data_reg;
+ assign systemace_data = systemace_data_reg;
+
+ // Instantiate the Unit Under Test (UUT)
+ CF_Interface uut (
+ .clk_27mhz(clk_27mhz),
+ .reset(reset),
+ .cmd(cmd),
+ .LBA(LBA),
+ .SC(SC),
+ .din(din),
+ .we_req(we_req),
+ .dout(dout),
+ .nd(nd),
+ .CF_detect(CF_detect),
+ .LBA_max(LBA_max),
+ .ready(ready),
+ .systemace_data(systemace_data),
+ .systemace_address(systemace_address),
+ .systemace_ce_b(systemace_ce_b),
+ .systemace_we_b(systemace_we_b),
+ .systemace_oe_b(systemace_oe_b),
+ .systemace_mpbrdy(systemace_mpbrdy)
+ );
+
+ // Clock is 100MHz
+ always clk_27mhz = ~clk_27mhz;
+
+ initial begin
+ // Initialize Inputs
+ clk_27mhz = 0;
+ reset = 0;
+ cmd = 0;
+ LBA = 0;
+ SC = 0;
+ din = 0;
+ systemace_mpbrdy = 0;
+
+ // Wait 100 ns for global reset to finish
+ #100;
+
+ // Add stimulus here
+
+ end
+
+endmodule
+
View
1,959 moar code/CF_Voicemail_Interface.v
@@ -0,0 +1,1959 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company: 6.111
+// Engineer: Sachin Shinde
+//
+// Create Date: 19:21:10 11/23/2012
+// Design Name:
+// Module Name: Voicemail_Interface
+// Project Name:
+// Target Devices:
+// Tool versions:
+// Description: Allows for reading and writing of voicemails to CompactFlash.
+// Voicemail max time is around 4 minutes (8192 sectors)
+// Max number of voicemails is 1024.
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////////
+//// High-Level Interface Module
+//////////////////////////////////////////////////////////////////////////////////
+
+module Voicemail_Interface(
+ input clk_27mhz, // 27MHz clock
+ input reset, // Synchronous reset
+ // Main Interface ports
+ output [3:0] sts, // Status port
+ input [3:0] cmd, // Port for issuing commands
+ input [7:0] phn_num, // Port for phone number (on writes)
+ input [15:0] din, // Sample Data in
+ output [15:0] dout, // Sample Data out
+ input d_ready, // Sample Data Ready Signal
+ input disp_en, // Display Enable
+ // Button inputs
+ input button_up,
+ input button_down,
+ // ASCII output
+ output [7:0] ascii_out, // Port for ASCII data
+ output ascii_out_ready, // Ready signal for ASCII data
+ // ZBT RAM I/Os
+ inout [35:0] ram_data,
+ output [18:0] ram_address,
+ output ram_we_b,
+ output [3:0] ram_bwe_b,
+ // Date & Time inputs
+ input [6:0] year,
+ input [3:0] month,
+ input [4:0] day,
+ input [4:0] hour,
+ input [5:0] minute,
+ input [5:0] second,
+ // Binary-to-Decimal Lookup-Table I/O
+ output [6:0] addr,
+ input [7:0] data,
+ // SystemACE ports
+ inout [15:0] systemace_data, // SystemACE R/W data
+ output [6:0] systemace_address, // SystemACE R/W address
+ output systemace_ce_b, // SystemACE chip enable (Active Low)
+ output systemace_we_b, // SystemACE write enable (Active Low)
+ output systemace_oe_b, // SystemACE output enable (Active Low)
+ input systemace_mpbrdy // SystemACE buffer ready
+ );
+
+ // Define command parameters
+ parameter CMD_IDLE = 4'd0;
+ parameter CMD_START_RD = 4'd1;
+ parameter CMD_END_RD = 4'd2;
+ parameter CMD_START_WR = 4'd3;
+ parameter CMD_END_WR = 4'd4;
+ parameter CMD_VIEW_UNRD = 4'd5;
+ parameter CMD_VIEW_SAVED = 4'd6;
+ parameter CMD_DEL = 4'd7;
+ parameter CMD_SAVE = 4'd8;
+
+ // Instantiate status register
+ reg [3:0] sts_reg;
+
+ // Assign status signal
+ assign sts = sts_reg;
+
+ // Define Status parameters
+ parameter STS_NO_CF_DEVICE = 4'd0;
+ parameter STS_CMD_RDY = 4'd1;
+ parameter STS_BUSY = 4'd2;
+ parameter STS_RDING = 4'd3;
+ parameter STS_RD_FIN = 4'd4;
+ parameter STS_WRING = 4'd5;
+ parameter STS_WR_FIN = 4'd6;
+ parameter STS_ERR_VM_FULL = 4'd7;
+ parameter STS_ERR_RD_FAIL = 4'd8;
+ parameter STS_ERR_WR_FAIL = 4'd9;
+
+ // Declare CF Interface command parameters
+ parameter CF_CMD_IDLE = 2'b00;
+ parameter CF_CMD_DETECT = 2'b01;
+ parameter CF_CMD_READ = 2'b10;
+ parameter CF_CMD_WRITE = 2'b11;
+
+ // Define ZBT Operation parameters (OPCODE)
+ parameter OP_IDLE = 2'b00;
+ parameter OP_READ = 2'b01;
+ parameter OP_WRITE = 2'b10;
+
+ // Instantiate state
+ reg [5:0] state;
+
+ // Define state parameters
+ parameter S_INIT = 6'h00;
+ parameter S_IDLE = 6'h01;
+ parameter S_START_RW_INIT = 6'h02;
+ parameter S_START_RW_INIT_1 = 6'h03;
+ parameter S_START_WR = 6'h04;
+ parameter S_START_WR_1 = 6'h05;
+ parameter S_START_WR_2 = 6'h06;
+ parameter S_START_WR_3 = 6'h07;
+ parameter S_START_WR_4 = 6'h08;
+ parameter S_WRING = 6'h09;
+ parameter S_END_WR = 6'h0A;
+ parameter S_END_WR_2 = 6'h0B;
+ parameter S_END_WR_3 = 6'h0C;
+ parameter S_START_RD = 6'h0D;
+ parameter S_START_RD_1 = 6'h0E;
+ parameter S_START_RD_2 = 6'h0F;
+ parameter S_RDING = 6'h10;
+ parameter S_END_RD = 6'h11;
+ parameter S_DEL_MSG = 6'h12;
+ parameter S_DEL_MSG_1 = 6'h13;
+ parameter S_DEL_MSG_2 = 6'h14;
+ parameter S_DEL_MSG_3 = 6'h15;
+ parameter S_DEL_MSG_4 = 6'h16;
+ parameter S_DEL_MSG_5 = 6'h17;
+ parameter S_ADD_MSG = 6'h18;
+ parameter S_ADD_MSG_1 = 6'h19;
+ parameter S_ADD_MSG_2 = 6'h1A;
+ parameter S_ADD_MSG_3 = 6'h1B;
+ parameter S_ADD_MSG_4 = 6'h1C;
+ parameter S_ADD_MSG_5 = 6'h1D;
+ parameter S_UPDT_MSG_POS_DATA = 6'h1E;
+ parameter S_UPDT_MSG_POS_DATA_1 = 6'h1F;
+ parameter S_UPDT_MSG_POS_DATA_2 = 6'h20;
+ parameter S_UPDT_MSG_POS_DATA_3 = 6'h21;
+ parameter S_UPDT_MSG_POS_DATA_4 = 6'h22;
+ parameter S_UPDT_MSG_POS_DATA_5 = 6'h23;
+ parameter S_UPDT_MSG_POS_DATA_6 = 6'h24;
+ parameter S_UPDT_MSG_POS_DATA_7 = 6'h25;
+ parameter S_UPDT_MSG_POS_DATA_8 = 6'h26;
+ parameter S_UPDT_MSG_POS_DATA_9 = 6'h27;
+ parameter S_UPDT_MSG_POS_DATA_10 = 6'h28;
+
+ // Generate button rise signals
+ reg bl_up, bl_down;
+ always @(posedge clk_27mhz) begin
+ if (reset) begin
+ bl_up <= 0;
+ bl_down <= 0;
+ end
+ else begin
+ bl_up <= button_up;
+ bl_down <= button_down;
+ end
+ end
+ assign b_up_rise = button_up & ~bl_up;
+ assign b_down_rise = button_down & ~bl_down;
+
+ // Instantiate CF_Interface
+ wire [1:0] CF_cmd;
+ wire [27:0] CF_LBA;
+ wire [7:0] CF_SC;
+ wire [15:0] CF_din;
+ wire CF_we_req;
+ wire [15:0] CF_dout;
+ wire CF_nd;
+ wire CF_CF_detect;
+ wire [27:0] CF_LBA_max;
+ wire CF_ready;
+ CF_Interface CF_INTERFACE_1(
+ .clk_27mhz(clk_27mhz), // 27 MHz clock
+ .reset(reset), // Synchronous reset
+ // Mid-level I/O
+ .cmd(CF_cmd), // Command to be performed
+ .LBA(CF_LBA), // Logical Block Address for r/w
+ .SC(CF_SC), // Sector Count
+ .din(CF_din), // Data input for writes
+ .we_req(CF_we_req), // Request for write data
+ .dout(CF_dout), // Data output for reads
+ .nd(CF_nd), // New Data available at output
+ .CF_detect(CF_CF_detect), // Detect if CF d evice is connected
+ .LBA_max(CF_LBA_max), // Maximum number of LBAs if CF detected
+ .ready(CF_ready), // Command ready signal
+ // SystemACE ports
+ .systemace_data(systemace_data), // SystemACE R/W data
+ .systemace_address(systemace_address), // SystemACE R/W address
+ .systemace_ce_b(systemace_ce_b), // SystemACE chip enable (Active Low)
+ .systemace_we_b(systemace_we_b), // SystemACE write enable (Active Low)
+ .systemace_oe_b(systemace_oe_b), // SystemACE output enable (Active Low)
+ .systemace_mpbrdy(systemace_mpbrdy) // SystemACE MPU buffer ready
+ );
+
+ // Instantiate CF Interface input registers
+ reg [1:0] CF_cmd_reg;
+ reg [27:0] CF_LBA_reg;
+ reg [7:0] CF_SC_reg;
+
+ // Assign CF Interface inputs
+ assign CF_cmd = CF_cmd_reg;
+ assign CF_LBA = CF_LBA_reg;
+ assign CF_SC = CF_SC_reg;
+
+ // Instantiate 4-Sector FIFO for Incoming Voicemail
+ reg wr_en_override, rst_in_FIFO;
+ wire [10:0] in_data_cnt;
+ wire in_wr_en;
+ assign in_wr_en = wr_en_override & d_ready;
+ wire in_full, in_empty;
+ Voicemail_FIFO VM_FIFO_IN(
+ .clk(clk_27mhz),
+ .rst(rst_in_FIFO),
+ .din(din),
+ .dout(CF_din),
+ .wr_en(in_wr_en),
+ .rd_en(CF_we_req),
+ .data_count(in_data_cnt),
+ .empty(in_empty),
+ .full(in_full)
+ );
+
+ // Instantiate 4-Sector FIFOs for Outgoing Voicemail
+ reg rd_en_override, rst_out_FIFO;
+ wire [10:0] out_data_cnt;
+ wire out_rd_en;
+ assign out_rd_en = rd_en_override & d_ready;
+ wire out_empty, out_full;
+ Voicemail_FIFO VM_FIFO_OUT(
+ .clk(clk_27mhz),
+ .rst(rst_out_FIFO),
+ .din(CF_dout),
+ .dout(dout),
+ .wr_en(CF_nd),
+ .rd_en(out_rd_en),
+ .data_count(out_data_cnt),
+ .empty(out_empty),
+ .full(out_full)
+ );
+
+ // Instantiate ZBT Interface
+ wire [35:0] ZBT_din, ZBT_dout;
+ wire [18:0] ZBT_addr;
+ wire [1:0] ZBT_op;
+ wire [3:0] ZBT_bwe;
+ wire ZBT_nd, ZBT_ready;
+ ZBT_Interface ZBT_INTERFACE_1(
+ .clk_27mhz(clk_27mhz), // 27MHz clock
+ .reset(reset), // Synchronous reset
+ // Low-Level I/O
+ .addr(ZBT_addr), // Address signal for r/w
+ .din(ZBT_din), // Data input for writes
+ .op(ZBT_op), // Operation Code
+ .bwe(ZBT_bwe), // Partial (byte) writes
+ .dout(ZBT_dout), // Data output for reads
+ .nd(ZBT_nd), // New data available at output
+ .ready(ZBT_ready), // Command Ready signal
+ // ZBT ports
+ .ram_data(ram_data),
+ .ram_address(ram_address),
+ .ram_we_b(ram_we_b),
+ .ram_bwe_b(ram_bwe_b)
+ );
+
+ // Instantiate ZBT Interface registers
+ reg [18:0] ZBT_addr_reg;
+ reg [35:0] ZBT_din_reg;
+ reg [1:0] ZBT_op_reg;
+ reg [3:0] ZBT_bwe_reg;
+
+ // Assign ZBT Interface registers
+ assign ZBT_addr = ZBT_addr_reg;
+ assign ZBT_din = ZBT_din_reg;
+ assign ZBT_op = ZBT_op_reg;
+ assign ZBT_bwe = ZBT_bwe_reg;
+
+ // Instantiate ZBT doubly-linked list (DLL) pointers
+ reg [14:0] unread_start;
+ reg [14:0] unread_end;
+ reg [14:0] saved_start;
+ reg [14:0] saved_end;
+
+ // Instantiate ZBT DLL message empty regs
+ reg unread_exist; // High if at least one unread message
+ reg saved_exist; // High if at least one saved message
+
+ // Instantiate ZBT FIFO pointers
+ reg [14:0] FIFO_start;
+ reg [14:0] FIFO_end;
+
+ // Instantiate CF Interface operation (internal) registers
+ reg [2:0] CF_Interface_op;
+
+ // Declare CF Interface operation parameters
+ parameter CF_OP_IDLE = 3'h0;
+ parameter CF_OP_WR_EN = 3'h1;
+ parameter CF_OP_RD_EN = 3'h2;
+ parameter CF_OP_WR_FORCE = 3'h3;
+ parameter CF_OP_DETECT = 3'h4;
+
+ // Latch input parameters
+ reg [7:0] latch_phn_num;
+ reg [32:0] latch_DT;
+
+ // Instantiate other internal registers
+ reg [14:0] msg_max; // Maximum number of messages
+ reg [14:0] msg_chkout_cnt; // Allocates message IDs initially
+ reg [21:0] sample_cnt; // Counts samples on R/W (0 to 8192*256 inclusive)
+ reg [14:0] msg_pos, msg_pos_prev, msg_pos_next; // Current message position and data
+ reg [7:0] msg_pos_phn_num; // Message position data
+ reg [32:0] msg_pos_DT; // Message position data
+ reg [21:0] msg_pos_sample_cnt; // Message position data
+ reg disp_req; // Set high for display request
+ reg S_DEL_save; // Parameter for delete procedure
+ reg S_ADD_MSG_unread; // Parameter for add message procedure
+ reg wr_op; // Used to control whether RD or WR op after Initial CF Detect
+ reg cur_view; // Currently viewed list (either 0 for unread, or 1 for saved)
+
+ // Manage main state transitions
+ always @(posedge clk_27mhz) begin
+ if (reset | ~CF_CF_detect) begin
+ // Set High-Level output registers
+ sts_reg <= STS_NO_CF_DEVICE;
+ // Set ZBT Interface output registers
+ ZBT_addr_reg <= 0;
+ ZBT_din_reg <= 0;
+ ZBT_op_reg <= OP_IDLE;
+ ZBT_bwe_reg <= 0;
+ // Set ZBT DLL pointers
+ unread_start <= 0;
+ unread_end <= 0;
+ saved_start <= 0;
+ saved_end <= 0;
+ unread_exist <= 0;
+ saved_exist <= 0;
+ // Set ZBT FIFO pointers
+ FIFO_start <= 0;
+ FIFO_end <= 0;
+ // Set override registers
+ rd_en_override <= 0;
+ wr_en_override <= 0;
+ // Set FIFO registers
+ rst_in_FIFO <= 0;
+ rst_out_FIFO <= 0;
+ // Set CF Interface op register
+ CF_Interface_op <= CF_OP_IDLE;
+ // Set Internal registers
+ msg_max <= 0;
+ msg_chkout_cnt <= 0;
+ sample_cnt <= 0;
+ msg_pos <= 0;
+ msg_pos_prev <= 0;
+ msg_pos_next <= 0;
+ msg_pos_phn_num <= 0;
+ msg_pos_DT <= 0;
+ msg_pos_sample_cnt <= 0;
+ disp_req <= 0;
+ wr_op <= 0;
+ cur_view <= 0;
+ // Set State
+ state <= S_INIT;
+ end
+ else begin
+ case (state)
+ S_INIT: begin
+ if (CF_ready) begin
+ // Set parent and child to itself
+ if (ZBT_ready) begin
+ msg_max <= CF_LBA_max[27:13];
+ sts_reg <= STS_CMD_RDY;
+ ZBT_addr_reg <= {2'b00, 15'd0, 2'b00};
+ ZBT_din_reg <= 36'd0;
+ ZBT_op_reg <= OP_WRITE;
+ ZBT_bwe_reg <= 4'b1111;
+ state <= state + 1; // S_IDLE
+ disp_req <= 1;
+ end
+ end
+ end
+ S_IDLE: begin
+ disp_req <= 0;
+ ZBT_op_reg <= OP_IDLE;
+ CF_Interface_op <= CF_OP_IDLE;
+ if ((b_up_rise | b_down_rise)&(unread_exist | cur_view)&(saved_exist | ~cur_view)) begin
+ sts_reg <= STS_BUSY;
+ case (b_up_rise)
+ 1'b0: begin // Down
+ state <= S_UPDT_MSG_POS_DATA;
+ msg_pos <= msg_pos_next;
+ end
+ 1'b1: begin // Up
+ state <= S_UPDT_MSG_POS_DATA;
+ msg_pos <= msg_pos_prev;
+ end
+ endcase
+ end
+ else begin
+ case (cmd)
+ CMD_START_RD: begin
+ state <= S_START_RW_INIT;
+ sts_reg <= STS_BUSY;
+ wr_op <= 0;
+ end
+ CMD_START_WR: begin
+ state <= S_START_RW_INIT;
+ latch_phn_num <= phn_num;
+ latch_DT <= {year, month, day, hour, minute, second};
+ sts_reg <= STS_BUSY;
+ wr_op <= 1;
+ end
+ CMD_VIEW_UNRD: begin
+ state <= S_UPDT_MSG_POS_DATA;
+ msg_pos <= unread_start;
+ sts_reg <= STS_BUSY;
+ cur_view <= 0;
+ end
+ CMD_VIEW_SAVED: begin
+ state <= S_UPDT_MSG_POS_DATA;
+ msg_pos <= saved_start;
+ sts_reg <= STS_BUSY;
+ cur_view <= 1;
+ end
+ CMD_DEL: begin
+ state <= S_DEL_MSG;
+ S_DEL_save <= 0;
+ sts_reg <= STS_BUSY;
+ end
+ CMD_SAVE: begin
+ if (~cur_view) begin // Make sure current view is unread
+ state <= S_DEL_MSG;
+ S_DEL_save <= 1;
+ sts_reg <= STS_BUSY;
+ end
+ else
+ sts_reg <= STS_CMD_RDY;
+ end
+ default: sts_reg <= STS_CMD_RDY;
+ endcase
+ end
+ end
+
+ /////////////////////////////////////////////////////////
+ //// Detect CF Device before RW operations
+ /////////////////////////////////////////////////////////
+
+ S_START_RW_INIT: begin // Detect CF device first
+ if (CF_cmd_reg == CF_CMD_DETECT) begin
+ CF_Interface_op <= CF_OP_IDLE; // S_START_WR_INIT_2
+ state <= state + 1; // S_START_RW_INIT_1
+ end
+ else
+ CF_Interface_op <= CF_OP_DETECT;
+ end
+ S_START_RW_INIT_1: begin // Wait for CF Interface to be ready before proceeding
+ if (CF_ready) begin
+ if (wr_op)
+ state <= state + 1; // S_START_WR
+ else
+ state <= S_START_RD;
+ end
+ end
+
+ /////////////////////////////////////////////////////////
+ //// Write Voicemail
+ /////////////////////////////////////////////////////////
+
+ S_START_WR: begin // Checkout message ID
+ sample_cnt <= 0;
+ rst_in_FIFO <= 1;
+ if (ZBT_ready) begin
+ if (msg_chkout_cnt != msg_max) begin
+ msg_chkout_cnt <= msg_chkout_cnt + 1;
+ msg_pos <= msg_chkout_cnt;
+ ZBT_addr_reg <= {2'b00, msg_chkout_cnt, 2'b01};
+ ZBT_din_reg <= {27'h0000000, latch_phn_num, 1'b0};
+ ZBT_op_reg <= OP_WRITE;
+ ZBT_bwe_reg <= 4'b0001;
+ state <= state + 2; // S_START_WR_2
+ end
+ else if (FIFO_start != FIFO_end) begin
+ ZBT_addr_reg <= {4'b0010, FIFO_start};
+ ZBT_op_reg <= OP_READ;
+ FIFO_start <= FIFO_start + 1;
+ state <= state + 1; // S_START_WR_1
+ end
+ else begin
+ state <= S_IDLE;
+ sts_reg <= STS_ERR_VM_FULL;
+ end
+ end
+ end
+ S_START_WR_1: begin
+ if (ZBT_nd) begin
+ ZBT_addr_reg <= {2'b00, ZBT_dout[35:21], 2'b01};
+ ZBT_din_reg <= {27'h0000000, latch_phn_num, 1'b0};
+ ZBT_op_reg <= OP_WRITE;
+ ZBT_bwe_reg <= 4'b0001;
+ msg_pos <= ZBT_dout[35:21];
+ state <= state + 2; // S_START_WR_3
+ end
+ else
+ ZBT_op_reg <= OP_IDLE;
+ end
+ S_START_WR_2: begin // Wait constraint on consective ZBT ops
+ ZBT_op_reg <= OP_IDLE;
+ state <= state + 1;
+ end
+ S_START_WR_3: begin // Store Date & Time
+ rst_in_FIFO <= 0;
+ if (ZBT_ready) begin
+ ZBT_addr_reg <= {2'b00, msg_pos, 2'b10};
+ ZBT_din_reg <= {latch_DT, 3'b000};
+ ZBT_op_reg <= OP_WRITE;
+ ZBT_bwe_reg <= 4'b1111;
+ state <= state + 1;
+ end
+ end
+ S_START_WR_4: begin // Wait constraint on consective ZBT ops
+ state <= S_ADD_MSG;
+ S_ADD_MSG_unread <= 1;
+ ZBT_op_reg <= OP_IDLE;
+ end
+ S_WRING: begin
+ ZBT_op_reg <= OP_IDLE;
+ if (cmd == CMD_END_WR) begin
+ sts_reg <= STS_WR_FIN;
+ wr_en_override <= 0;
+ state <= state + 1; // S_END_WR
+ end
+ else if (d_ready) begin
+ if (in_full) begin // if write buffer full
+ sts_reg <= STS_ERR_WR_FAIL;
+ wr_en_override <= 0;
+ state <= state + 1; // S_END_WR
+ end
+ else if (&sample_cnt[20:0]) begin // if next sample will be last
+ sts_reg <= STS_WR_FIN;
+ wr_en_override <= 0;
+ state <= state + 1; // S_END_WR
+ sample_cnt <= sample_cnt + 1;
+ end
+ else
+ sample_cnt <= sample_cnt + 1;
+ end
+ end
+ S_END_WR: begin
+ if (!in_data_cnt[10:8] & CF_ready) begin
+ state <= state + 1; // S_END_WR_2
+ if (in_data_cnt[7:0]) begin // if there are samples left in the incoming FIFO
+ CF_Interface_op <= CF_OP_WR_FORCE; // force remainder of FIFO to be written
+ end
+ else begin
+ CF_Interface_op <= CF_OP_IDLE;
+ end
+ end
+ end
+ S_END_WR_2: begin
+ if (!in_data_cnt && CF_ready) begin // wait until incoming FIFO is empty and CF Interface is ready before moving forward
+ state <= state + 1;
+ CF_Interface_op <= CF_OP_IDLE;
+ end
+ end
+ S_END_WR_3: begin // Store sample count (ZBT should be ready, no need to check)
+ ZBT_addr_reg <= {2'b00, msg_pos, 2'b01};
+ ZBT_din_reg <= {sample_cnt, 14'd0};
+ ZBT_op_reg <= OP_WRITE;
+ ZBT_bwe_reg <= 4'b1110;
+ state <= S_IDLE;
+ sts_reg <= STS_CMD_RDY;
+ end
+
+ /////////////////////////////////////////////////////////
+ //// Read Voicemail
+ /////////////////////////////////////////////////////////
+
+ S_START_RD: begin // check if message exists before reading
+ if ((~unread_exist & ~cur_view)|(~saved_exist & cur_view)) begin
+ state <= S_IDLE;
+ sts_reg <= STS_CMD_RDY;
+ end
+ else
+ state <= state + 1; // S_START_RD_1
+ end
+ S_START_RD_1: begin
+ sample_cnt <= msg_pos_sample_cnt;
+ rst_out_FIFO <= 1;
+ state <= state + 1; // S_START_RD_2
+ end
+ S_START_RD_2: begin
+ rst_out_FIFO <= 0;
+ CF_Interface_op <= CF_OP_RD_EN;
+ if (out_data_cnt[10:8]) begin // Preload 256 samples into output FIFO before proceeding
+ state <= state + 1; // S_RDING
+ sts_reg <= STS_RDING;
+ rd_en_override <= 1;
+ end
+ end
+ S_RDING: begin
+ if (cmd == CMD_END_RD) begin
+ sts_reg <= STS_RD_FIN;
+ rd_en_override <= 0;
+ CF_Interface_op <= CF_OP_IDLE;
+ state <= state + 1; // S_END_RD
+ end
+ else if (d_ready) begin
+ if (out_empty) begin // if read buffer empty
+ sts_reg <= STS_ERR_RD_FAIL;
+ rd_en_override <= 0;
+ CF_Interface_op <= CF_OP_IDLE;
+ state <= state + 1; // S_END_RD
+ end
+ else if (sample_cnt == 1) begin // if next sample will be last
+ sts_reg <= STS_RD_FIN;
+ rd_en_override <= 0;
+ CF_Interface_op <= CF_OP_IDLE;
+ state <= state + 1; // S_END_RD
+ end
+ else
+ sample_cnt <= sample_cnt - 1;
+ end
+ end
+ S_END_RD: begin // Wait until CF Interface is ready before moving forward
+ if (CF_ready) begin
+ state <= S_IDLE;
+ sts_reg <= STS_CMD_RDY;
+ end
+ end
+
+ /////////////////////////////////////////////////////////
+ //// Delete Message from List
+ /////////////////////////////////////////////////////////
+
+ S_DEL_MSG: begin
+ if ((~unread_exist & ~cur_view)|(~saved_exist & cur_view)) begin // Check if del/sve cmd issued when lists are empty
+ state <= S_IDLE;
+ sts_reg <= STS_CMD_RDY;
+ end
+ else
+ state <= state + 1; // S_DEL_MSG_1
+ end
+ S_DEL_MSG_1: begin
+ if (ZBT_ready) begin
+ ZBT_addr_reg <= {2'b00, msg_pos_prev, 2'b00}; // Set previous msg's child to next msg
+ ZBT_din_reg <= {18'h00000, msg_pos_next, 3'b000};
+ ZBT_op_reg <= OP_WRITE;
+ ZBT_bwe_reg <= 4'b0011;
+ state <= state + 1; // S_DEL_MSG_2
+ // Update if msg to delete is start or end of a list;
+ if (cur_view) begin
+ if (msg_pos == saved_end) saved_end <= msg_pos_prev;
+ if (msg_pos == saved_start) saved_start <= msg_pos_next;
+ end
+ else begin
+ if (msg_pos == unread_end) unread_end <= msg_pos_prev;
+ if (msg_pos == unread_start) unread_start <= msg_pos_next;
+ end
+ end
+ end
+ S_DEL_MSG_2: begin // Wait constraint on consective ZBT ops
+ state <= state + 1; // S_DEL_MSG_3
+ ZBT_op_reg <= OP_IDLE;
+ end
+ S_DEL_MSG_3: begin
+ if (ZBT_ready) begin
+ ZBT_addr_reg <= {2'b00, msg_pos_next, 2'b00}; // Set next msg's parent to previous msg
+ ZBT_din_reg <= {msg_pos_prev, 21'h000000};
+ ZBT_op_reg <= OP_WRITE;
+ ZBT_bwe_reg <= 4'b1100;
+ state <= state + 1; // S_DEL_MSG_4
+ end
+ end
+ S_DEL_MSG_4: begin // Wait constraint on consective ZBT ops
+ state <= state + 1; // S_DEL_MSG_5
+ ZBT_op_reg <= OP_IDLE;
+ end
+ S_DEL_MSG_5: begin
+ if (ZBT_ready) begin
+ if (msg_pos_prev == msg_pos) begin // Check if only one message left
+ if (cur_view)
+ saved_exist <= 0;
+ else
+ unread_exist <= 0;
+ end
+ if (S_DEL_save) begin
+ ZBT_op_reg <= OP_IDLE;
+ state <= S_ADD_MSG;
+ S_ADD_MSG_unread <= 0;
+ end
+ else begin // Add deleted msg ID to end of FIFO
+ ZBT_addr_reg <= {4'b0100, FIFO_end};
+ ZBT_din_reg <= {msg_pos, 21'h000000};
+ ZBT_op_reg <= OP_WRITE;
+ ZBT_bwe_reg <= 4'b1111;
+ FIFO_end <= FIFO_end + 1;
+ msg_pos <= msg_pos_prev;
+ state <= S_UPDT_MSG_POS_DATA;
+ end
+ end
+ end
+
+ /////////////////////////////////////////////////////////
+ //// Add Message to End of List
+ /////////////////////////////////////////////////////////
+
+ S_ADD_MSG: begin // Wait constraint on consective ZBT ops
+ state <= state + 1; // S_ADD_MSG_1
+ ZBT_op_reg <= OP_IDLE;
+ end
+ S_ADD_MSG_1: begin
+ if (ZBT_ready) begin
+ ZBT_op_reg <= OP_WRITE;
+ ZBT_addr_reg <= {2'b00, msg_pos, 2'b00};
+ ZBT_bwe_reg <= 4'b1111;
+ if (S_ADD_MSG_unread) begin // writing
+ if (unread_exist) begin
+ ZBT_din_reg <= {unread_end, 3'b000, unread_start, 3'b000};
+ state <= state + 1; // S_ADD_MSG_2
+ end
+ else begin
+ ZBT_din_reg <= {msg_pos, 3'b000, msg_pos, 3'b000};
+ unread_start <= msg_pos;
+ unread_end <= msg_pos;
+ unread_exist <= 1;
+ state <= S_WRING;
+ sts_reg <= STS_WRING;
+ wr_en_override <= 1;
+ CF_Interface_op <= CF_OP_WR_EN;
+ end
+ end
+ else begin // saving
+ if (saved_exist) begin
+ ZBT_din_reg <= {saved_end, 3'b000, saved_start, 3'b000};
+ state <= state + 1; // S_ADD_MSG_2
+ end
+ else begin
+ ZBT_din_reg <= {msg_pos, 3'b000, msg_pos, 3'b000};
+ saved_start <= msg_pos;
+ saved_end <= msg_pos;
+ saved_exist <= 1;
+ state <= S_UPDT_MSG_POS_DATA;
+ msg_pos <= msg_pos_prev;
+ end
+ end
+ end
+ end
+ S_ADD_MSG_2: begin // Wait constraint on consective ZBT ops
+ state <= state + 1; // S_ADD_MSG_3
+ ZBT_op_reg <= OP_IDLE;
+ end
+ S_ADD_MSG_3: begin // Set start's parent to message
+ if (ZBT_ready) begin
+ ZBT_op_reg <= OP_WRITE;
+ ZBT_bwe_reg <= 4'b1100;
+ ZBT_din_reg <= {msg_pos, 21'h000000};
+ state <= state + 1; // S_ADD_MSG_4
+ if (S_ADD_MSG_unread)
+ ZBT_addr_reg <= {2'b00, unread_start, 2'b00};
+ else
+ ZBT_addr_reg <= {2'b00, saved_start, 2'b00};
+ end
+ end
+ S_ADD_MSG_4: begin // Wait constraint on consective ZBT ops
+ state <= state + 1; // S_ADD_MSG_5
+ ZBT_op_reg <= OP_IDLE;
+ end
+ S_ADD_MSG_5: begin // Set end's child to message
+ if (ZBT_ready) begin
+ ZBT_op_reg <= OP_WRITE;
+ ZBT_bwe_reg <= 4'b0011;
+ ZBT_din_reg <= {18'h00000, msg_pos, 3'b000};
+ if (S_ADD_MSG_unread) begin
+ ZBT_addr_reg <= {2'b00, unread_end, 2'b00};
+ unread_end <= msg_pos;
+ state <= S_WRING;
+ sts_reg <= STS_WRING;
+ wr_en_override <= 1;
+ CF_Interface_op <= CF_OP_WR_EN;
+ end
+ else begin
+ ZBT_addr_reg <= {2'b00, saved_end, 2'b00};
+ saved_end <= msg_pos;
+ state <= S_UPDT_MSG_POS_DATA;
+ msg_pos <= msg_pos_prev;
+ end
+ end
+ end
+
+ /////////////////////////////////////////////////////////
+ //// Update Message Position Data
+ /////////////////////////////////////////////////////////
+
+ S_UPDT_MSG_POS_DATA: begin // Wait constraint on consective ZBT ops
+ state <= state + 1; // S_UPDT_MSG_POS_DATA_1
+ ZBT_op_reg <= OP_IDLE;
+ end
+ S_UPDT_MSG_POS_DATA_1: begin
+ if (ZBT_ready) begin
+ ZBT_addr_reg <= {2'b00, msg_pos, 2'b00}; // Read Parent (Prev) & Child (Next)
+ ZBT_op_reg <= OP_READ;
+ state <= state + 1; // S_UPDT_MSG_POS_DATA_2
+ end
+ end
+ S_UPDT_MSG_POS_DATA_2: begin // Wait constraint on consective ZBT ops
+ state <= state + 1; // S_UPDT_MSG_POS_DATA_3
+ ZBT_op_reg <= OP_IDLE;
+ end
+ S_UPDT_MSG_POS_DATA_3: begin
+ ZBT_addr_reg <= {2'b00, msg_pos, 2'b01}; // Read Sample Count & Phone number
+ ZBT_op_reg <= OP_READ;
+ state <= state + 1; // S_UPDT_MSG_POS_DATA_4
+ end
+ S_UPDT_MSG_POS_DATA_4: begin // Wait constraint on consective ZBT ops
+ state <= state + 1; // S_UPDT_MSG_POS_DATA_5
+ ZBT_op_reg <= OP_IDLE;
+ end
+ S_UPDT_MSG_POS_DATA_5: begin
+ ZBT_addr_reg <= {2'b00, msg_pos, 2'b10}; // Read Date & Time
+ ZBT_op_reg <= OP_READ;
+ state <= state + 1; // S_UPDT_MSG_POS_DATA_6
+ end
+ S_UPDT_MSG_POS_DATA_6: begin
+ ZBT_op_reg <= OP_IDLE;
+ msg_pos_prev <= ZBT_dout[35:21];
+ msg_pos_next <= ZBT_dout[17:3];
+ state <= state + 1; // S_UPDT_MSG_POS_DATA_7
+ end
+ S_UPDT_MSG_POS_DATA_7: begin
+ state <= state + 1; // S_UPDT_MSG_POS_DATA_8
+ end
+ S_UPDT_MSG_POS_DATA_8: begin
+ msg_pos_sample_cnt <= ZBT_dout[35:14];
+ msg_pos_phn_num <= ZBT_dout[8:1];
+ state <= state + 1; // S_UPDT_MSG_POS_DATA_9
+ end
+ S_UPDT_MSG_POS_DATA_9: begin
+ state <= state + 1; // S_UPDT_MSG_POS_DATA_10
+ end
+ S_UPDT_MSG_POS_DATA_10: begin
+ msg_pos_DT <= ZBT_dout[35:3];
+ sts_reg <= STS_CMD_RDY;
+ state <= S_IDLE;
+ disp_req <= 1;
+ end
+ endcase
+ end
+ end
+
+ // Manage commands to CF Interface as needed
+ reg [12:0] cur_LBA;
+ wire [7:0] in_SC, out_SC;
+ wire [1:0] out_SC_low;
+ assign in_SC = (in_data_cnt[10]) ? 8'd4: {6'd0, in_data_cnt[9:8]};
+ assign out_SC_low = 2'd3 - out_data_cnt[9:8];
+ assign out_SC = (out_data_cnt[10]) ? 8'd0: {6'd0, out_SC_low};
+ always @(posedge clk_27mhz) begin
+ if (reset) begin
+ CF_cmd_reg <= CF_CMD_IDLE;
+ CF_LBA_reg <= 0;
+ CF_SC_reg <= 0;
+ cur_LBA <= 0;
+ end
+ else begin
+ case (CF_Interface_op)
+ CF_OP_WR_EN: begin
+ if (CF_ready && in_SC) begin
+ CF_cmd_reg <= CF_CMD_WRITE;
+ CF_LBA_reg <= {msg_pos, cur_LBA};
+ CF_SC_reg <= in_SC;
+ cur_LBA <= (cur_LBA + CF_SC_reg);
+ end
+ else
+ CF_cmd_reg <= CF_CMD_IDLE;
+ end
+ CF_OP_RD_EN: begin
+ if (CF_ready && out_SC) begin
+ CF_cmd_reg <= CF_CMD_READ;
+ CF_LBA_reg <= {msg_pos, cur_LBA};
+ CF_SC_reg <= out_SC;
+ cur_LBA <= (cur_LBA + CF_SC_reg);
+ end
+ else
+ CF_cmd_reg <= CF_CMD_IDLE;
+ end
+ CF_OP_WR_FORCE: begin
+ if (CF_ready && in_data_cnt) begin
+ CF_cmd_reg <= CF_CMD_WRITE;
+ CF_LBA_reg <= {msg_pos, cur_LBA};
+ CF_SC_reg <= 1;
+ end
+ else
+ CF_cmd_reg <= CF_CMD_IDLE;
+ end
+ CF_OP_DETECT: begin
+ if (CF_ready)
+ CF_cmd_reg <= CF_CMD_DETECT;
+ end
+ default: begin // CD_OP_IDLE
+ CF_cmd_reg <= CF_CMD_IDLE;
+ cur_LBA <= 0;
+ CF_SC_reg <= 0;
+ end
+
+ endcase
+ end
+ end
+
+ // Instantiate ASCII state
+ reg [4:0] ascii_state;
+
+ // Declare ASCII state parameters
+ parameter S_ASCII_IDLE = 5'h00;
+ parameter S_ASCII_DISP = 5'h01;
+ parameter S_ASCII_DISP_1 = 5'h02;
+ parameter S_ASCII_DISP_2 = 5'h03;
+ parameter S_ASCII_DISP_3 = 5'h04;
+ parameter S_ASCII_DISP_4 = 5'h05;
+ parameter S_ASCII_DISP_5 = 5'h06;
+ parameter S_ASCII_DISP_6 = 5'h07;
+ parameter S_ASCII_DISP_7 = 5'h08;
+ parameter S_ASCII_DISP_8 = 5'h09;
+ parameter S_ASCII_DISP_9 = 5'h0A;
+ parameter S_ASCII_DISP_10 = 5'h0B;
+ parameter S_ASCII_DISP_11 = 5'h0C;
+ parameter S_ASCII_DISP_12 = 5'h0D;
+ parameter S_ASCII_DISP_13 = 5'h0E;
+ parameter S_ASCII_DISP_14 = 5'h0F;
+ parameter S_ASCII_DISP_15 = 5'h10;
+ parameter S_ASCII_DISP_16 = 5'h11;
+ parameter S_ASCII_DISP_17 = 5'h12;
+ parameter S_ASCII_DISP_18 = 5'h13;
+ parameter S_ASCII_DISP_19 = 5'h14;
+ parameter S_ASCII_DISP_20 = 5'h15;
+ parameter S_ASCII_DISP_EMPTY = 5'h16;
+ parameter S_ASCII_DISP_EMPTY_1 = 5'h17;
+ parameter S_ASCII_DISP_EMPTY_2 = 5'h18;
+ parameter S_ASCII_DISP_EMPTY_3 = 5'h19;
+
+
+ // Instantiate ASCII registers
+ reg [7:0] ascii_out_reg;
+ reg ascii_out_ready_reg;
+ reg [6:0] addr_reg;
+
+ // Assign ASCII registers
+ assign ascii_out = ascii_out_reg;
+ assign ascii_out_ready = ascii_out_ready_reg;
+ assign addr = addr_reg;
+
+ // Instantiate capture registers
+ reg [25:0] DT_capture;
+ reg [7:0] phn_num_capture;
+ reg [3:0] phn_num_minus_nine;
+ reg empty_capture;
+
+ // Queue display requests as needed
+ reg q_disp_req, l_disp_req;
+ always @(posedge clk_27mhz) begin
+ if (reset) begin
+ l_disp_req <= 0;
+ end
+ else if (disp_req) begin // latch if high
+ l_disp_req <= 1;
+ end
+ else if (ascii_state == S_ASCII_IDLE) begin
+ l_disp_req <= 0;
+ end
+ end
+ always @(posedge clk_27mhz) begin
+ if (reset) begin
+ q_disp_req <= 0;
+ end
+ else if (l_disp_req & (ascii_state == S_ASCII_IDLE)) begin
+ q_disp_req <= 1;
+ end
+ else begin
+ q_disp_req <= 0;
+ end
+ end
+
+ // Manage ASCII output when display requested or enabled
+ always @(posedge clk_27mhz) begin
+ if (reset) begin
+ ascii_state <= 0; // S_ASCII_IDLE
+ ascii_out_reg <= 0;
+ ascii_out_ready_reg <= 0;
+ addr_reg <= 0;
+ DT_capture <= 0;
+ phn_num_capture <= 0;
+ empty_capture <= 0;
+ end
+ else begin
+ case (ascii_state)
+ S_ASCII_IDLE: begin
+ ascii_out_reg <= 0;
+ ascii_out_ready_reg <= 0;
+ addr_reg <= msg_pos_DT[32:26];
+ if (disp_en & q_disp_req) begin
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP
+ DT_capture <= msg_pos_DT[25:0];
+ phn_num_capture <= msg_pos_phn_num;
+ empty_capture <= ((~unread_exist & ~cur_view)|(~saved_exist & cur_view));
+ end
+ end
+ S_ASCII_DISP: begin
+ if (empty_capture) // Test if empty
+ ascii_state <= S_ASCII_DISP_EMPTY;
+ else
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_1
+ end
+ S_ASCII_DISP_1: begin
+ addr_reg <= {3'b000, DT_capture[25:22]};
+ ascii_out_reg <= {4'b0011, data[7:4]}; // year, first digit
+ ascii_out_ready_reg <= 1;
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_2
+ end
+ S_ASCII_DISP_2: begin
+ ascii_out_reg <= {4'b0011, data[3:0]}; // year, second digit
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_3
+ end
+ S_ASCII_DISP_3: begin
+ ascii_out_reg <= 8'h2F; // forward slash
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_4
+ end
+ S_ASCII_DISP_4: begin
+ addr_reg <= {2'b00, DT_capture[21:17]};
+ ascii_out_reg <= {4'b0011, data[7:4]}; // month, first digit
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_5
+ end
+ S_ASCII_DISP_5: begin
+ ascii_out_reg <= {4'b0011, data[3:0]}; // month, second digit
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_6
+ end
+ S_ASCII_DISP_6: begin
+ ascii_out_reg <= 8'h2F; // forward slash
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_7
+ end
+ S_ASCII_DISP_7: begin
+ addr_reg <= {2'b00, DT_capture[16:12]};
+ ascii_out_reg <= {4'b0011, data[7:4]}; // day, first digit
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_8
+ end
+ S_ASCII_DISP_8: begin
+ ascii_out_reg <= {4'b0011, data[3:0]}; // day, second digit
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_9
+ end
+ S_ASCII_DISP_9: begin
+ ascii_out_reg <= 8'h20; // space
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_10
+ end
+ S_ASCII_DISP_10: begin
+ addr_reg <= {1'b0, DT_capture[11:6]};
+ ascii_out_reg <= {4'b0011, data[7:4]}; // hour, first digit
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_11
+ end
+ S_ASCII_DISP_11: begin
+ ascii_out_reg <= {4'b0011, data[3:0]}; // hour, second digit
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_12
+ end
+ S_ASCII_DISP_12: begin
+ ascii_out_reg <= 8'h3A; // colon
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_13
+ end
+ S_ASCII_DISP_13: begin
+ addr_reg <= {1'b0, DT_capture[5:0]};
+ ascii_out_reg <= {4'b0011, data[7:4]}; // minute, first digit
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_14
+ end
+ S_ASCII_DISP_14: begin
+ ascii_out_reg <= {4'b0011, data[3:0]}; // minute, second digit
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_15
+ end
+ S_ASCII_DISP_15: begin
+ ascii_out_reg <= 8'h3A; // colon
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_16
+ end
+ S_ASCII_DISP_16: begin
+ ascii_out_reg <= {4'b0011, data[7:4]}; // second, first digit
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_17
+ end
+ S_ASCII_DISP_17: begin
+ ascii_out_reg <= {4'b0011, data[3:0]}; // second, second digit
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_18
+ end
+ S_ASCII_DISP_18: begin
+ ascii_out_reg <= 8'h20; // space
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_19
+ phn_num_minus_nine <= phn_num_capture[7:4] - 4'd9;
+ end
+ S_ASCII_DISP_19: begin
+ ascii_out_reg <= (phn_num_capture[7:4] < 4'd10) ? {4'b0011, phn_num_capture[7:4]}: {4'b0100, phn_num_minus_nine};
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_20
+ phn_num_minus_nine <= phn_num_capture[3:0] - 4'd9;
+ end
+ S_ASCII_DISP_20: begin
+ ascii_out_reg <= (phn_num_capture[3:0] < 4'd10) ? {4'b0011, phn_num_capture[3:0]}: {4'b0100, phn_num_minus_nine};
+ ascii_state <= S_ASCII_IDLE;
+ end
+ S_ASCII_DISP_EMPTY: begin // Display "None" since empty
+ ascii_out_reg <= 8'h4E; // N
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_EMPTY_1
+ ascii_out_ready_reg <= 1;
+ end
+ S_ASCII_DISP_EMPTY_1: begin
+ ascii_out_reg <= 8'h6F; // o
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_EMPTY_2
+ end
+ S_ASCII_DISP_EMPTY_2: begin
+ ascii_out_reg <= 8'h6E; // n
+ ascii_state <= ascii_state + 1; // S_ASCII_DISP_EMPTY_3
+ end
+ S_ASCII_DISP_EMPTY_3: begin
+ ascii_out_reg <= 8'h65; // e
+ ascii_state <= S_ASCII_IDLE;
+ end
+ endcase
+ end
+ end
+endmodule
+
+//////////////////////////////////////////////////////////////////////////////////
+//// Mid-Level Interface Module
+//////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////////
+// Provide a mid-level interface for making reads and writes to Compact Flash.
+// READING:
+// o On read request, provide read command, LBA, and sector count (SC).
+// o Sends back data in 16-bit words as it arrives with nd (new data) signal.
+// WRITING:
+// o On write request, provide write command, LBA, and sector count (SC).
+// o Sends back we_req for requesting write data to be sent.
+// o Write data must be sent during the SAME clock cycle we_req is asserted.
+// o Use FWFT on any external FIFOs for 0 latency reads from the FIFOs.
+// STATUS:
+// o Tells if Compact Flash device is present. Manual CF Detect commands
+// needed in idle state. Done automatically when needed for R/W.
+// o If CF device is present, gives number of LBAs on device.
+// o Provides signal indicating whether system is ready for command.
+// COMMANDS:
+// o CMD_IDLE: 2'b00
+// o CMD_DETECT: 2'b01
+// o CMD_READ: 2'b10
+// o CMD_WRITE: 2'b11
+// SPECIAL NOTES:
+// o SC value of 0 corresponds to 256.
+// o Ready signal is asserted cycle BEFORE data can be issued.
+// o Ensure successive commands have at least one cycle between them.
+//////////////////////////////////////////////////////////////////////////////////
+
+module CF_Interface #(
+ parameter CMD_RDY_TO_PD = 1620000, // SystemACE Command Ready Timeout Period
+ parameter BFR_RDY_TO_PD = 1620000 // SystemACE Buffer Ready Timeout Period
+ )(
+ input clk_27mhz, // 27 MHz clock
+ input reset, // Synchronous reset
+ // Mid-level I/O
+ input [1:0] cmd, // Command to be performed
+ input [27:0] LBA, // Logical Block Address for r/w
+ input [7:0] SC, // Sector Count
+ input [15:0] din, // Data input for writes
+ output we_req, // Request for write data
+ output [15:0] dout, // Data output for reads
+ output nd, // New Data available at output
+ output CF_detect, // Detect if CF device is connected
+ output [27:0] LBA_max, // Maximum number of LBAs if CF detected
+ output ready, // Command ready signal
+ // SystemACE ports
+ inout [15:0] systemace_data, // SystemACE R/W data
+ output [6:0] systemace_address, // SystemACE R/W address
+ output systemace_ce_b, // SystemACE chip enable (Active Low)
+ output systemace_we_b, // SystemACE write enable (Active Low)
+ output systemace_oe_b, // SystemACE output enable (Active Low)
+ input systemace_mpbrdy // SystemACE MPU buffer ready
+ );
+
+ // Instantiate Low-Level I/O for basic R/W to SystemACE MPU
+ wire [15:0] rw_din, rw_dout;
+ wire [5:0] addr;
+ wire [6:0] addr_large;
+ wire re, we, rw_nd, rw_ready;
+ assign addr_large = {addr, 1'b0};
+ RW_Interface RW_INTERFACE_1(
+ .clk_27mhz(clk_27mhz),
+ .reset(reset),
+ // RW ports
+ .addr(addr_large),
+ .din(rw_din),
+ .we(we),
+ .re(re),
+ .dout(rw_dout),
+ .nd(rw_nd),
+ .ready(rw_ready),
+ // SystemACE ports
+ .systemace_data(systemace_data),
+ .systemace_address(systemace_address),
+ .systemace_ce_b(systemace_ce_b),
+ .systemace_we_b(systemace_we_b),
+ .systemace_oe_b(systemace_oe_b)
+ );
+
+ // Declare command parameters
+ parameter CMD_IDLE = 2'b00;
+ parameter CMD_DETECT = 2'b01;
+ parameter CMD_READ = 2'b10;
+ parameter CMD_WRITE = 2'b11;
+
+ // Instantiate state
+ reg [5:0] state;
+
+ // Declare state parameters
+ parameter S_SET_WORD_MODE = 6'h00;
+ parameter S_SET_WORD_MODE_1 = 6'h01;
+ parameter S_FORCE_LOCK = 6'h02;
+ parameter S_FORCE_LOCK_1 = 6'h03;
+ parameter S_CHK_LOCK = 6'h04;
+ parameter S_CHK_LOCK_1 = 6'h05;
+ parameter S_IDLE = 6'h06;
+ parameter S_CHK_RDY = 6'h07;
+ parameter S_CHK_RDY_1 = 6'h08;
+ parameter S_CHK_RDY_2 = 6'h09;
+ parameter S_SET_LBA = 6'h0A;
+ parameter S_SET_LBA_1 = 6'h0B;
+ parameter S_SET_LBA_2 = 6'h0C;
+ parameter S_SET_LBA_3 = 6'h0D;
+ parameter S_SET_SC_CMD = 6'h0E;
+ parameter S_SET_SC_CMD_1 = 6'h0F;
+ parameter S_RESET_CFG = 6'h10;
+ parameter S_RESET_CFG_1 = 6'h11;
+ parameter S_INIT_BFR_CNT = 6'h12;
+ parameter S_CHK_BFR_RDY = 6'h13;
+ parameter S_CHK_BFR_RDY_1 = 6'h14;
+ parameter S_CHK_BFR_RDY_2 = 6'h15;
+ parameter S_CHK_BFR_RDY_3 = 6'h16;
+ parameter S_INIT_DATA_CNT = 6'h17;
+ parameter S_WR_BFR = 6'h18;
+ parameter S_WR_BFR_1 = 6'h19;
+ parameter S_RD_BFR = 6'h1A;
+ parameter S_RD_BFR_1 = 6'h1B;
+ parameter S_RD_BFR_2 = 6'h1C;
+ parameter S_CLR_RESET_CFG = 6'h1D;
+ parameter S_CLR_RESET_CFG_1 = 6'h1E;
+ parameter S_ABORT_CMD = 6'h1F;
+ parameter S_ABORT_CMD_1 = 6'h20;
+ parameter S_ABORT_CMD_2 = 6'h21;
+ parameter S_ABORT_CMD_3 = 6'h22;
+ parameter S_CF_DETECT = 6'h23;
+ parameter S_CF_DETECT_1 = 6'h24;
+ parameter S_CF_DETECT_FAIL = 6'h25;
+ parameter S_CF_DETECT_FAIL_1 = 6'h26;
+
+ // Instantiate RW Interface input registers
+ reg [5:0] addr_reg;
+ reg [15:0] rw_din_reg;
+ reg re_reg, we_reg;
+
+ // Assign RW Interface inputs
+ assign addr = addr_reg;
+ assign rw_din = rw_din_reg;
+ assign we = we_reg;
+ assign re = re_reg;
+
+ // Instantiate Mid-Level output registers
+ reg we_req_reg;
+ reg nd_reg;
+ reg CF_detect_reg;
+ reg [27:0] LBA_max_reg;
+ reg ready_reg;
+
+ // Assign Mid-Level outputs
+ assign we_req = we_req_reg;
+ assign dout = rw_dout;
+ assign nd = nd_reg;
+ assign CF_detect = CF_detect_reg;
+ assign LBA_max = LBA_max_reg;
+ assign ready = ready_reg;
+
+ // Instantiate return states for function calls
+ reg [5:0] rtn_state_CF_detect;
+
+ // Instantiate op register for passing function parameters
+ reg [1:0] op_reg;
+
+ // Declare op parameters
+ parameter OP_IDENTIFY = 2'h0;
+ parameter OP_READ = 2'h1;
+ parameter OP_WRITE = 2'h2;
+
+ // Instantiate registers for storing Mid-Level input
+ reg [27:0] LBA_reg;
+ reg [7:0] SC_reg;
+
+ // Instantiate internal registers
+ reg nd_raw_reg;
+ reg [3:0] data_cnt;
+ reg [11:0] bfr_cnt;
+ reg [20:0] timeout_cntr; // Ensure enough bits for TO_PD parameters
+
+ // Manage state transitions
+ always @(posedge clk_27mhz) begin
+ if (reset) begin
+ // RW Interface Inputs
+ addr_reg <= 0;
+ rw_din_reg <= 0;
+ we_reg <= 0;
+ re_reg <= 0;
+ // Mid-Level outputs
+ we_req_reg <= 0;
+ nd_reg <= 0;
+ CF_detect_reg <= 0;
+ LBA_max_reg <= 0;
+ ready_reg <= 0;
+ // Mid-Level inputs
+ LBA_reg <= 0;
+ SC_reg <= 0;
+ // Internal regsiters
+ nd_raw_reg <= 0;
+ data_cnt <= 0;
+ bfr_cnt <= 0;
+ timeout_cntr <= 0;
+ // Set state to enter after reset
+ state <= 0; // S_SET_WORD_MODE
+ rtn_state_CF_detect <= S_CF_DETECT_FAIL;
+ end
+ else
+ case (state)
+ S_SET_WORD_MODE: begin // Set Bus Mode to WORD MODE
+ if (rw_ready) begin
+ addr_reg <= 6'h00; // Write BUSMODEREG[7:0]
+ rw_din_reg <= 16'h0001;
+ re_reg <= 0;
+ we_reg <= 1;
+ state <= state + 1; // S_SET_WORD_MODE_1
+ end
+ end
+ S_SET_WORD_MODE_1: begin
+ re_reg <= 0;
+ we_reg <= 0;
+ state <= state + 1; // S_FORCE_LOCK
+ end
+ S_FORCE_LOCK: begin // Force lock on CompactFlash resource
+ if (rw_ready) begin
+ addr_reg <= 6'h0C; // Write CONTROLREG[15:0]
+ rw_din_reg <= 16'h0003;
+ re_reg <= 0;
+ we_reg <= 1;
+ state <= state + 1; // S_FORCE_LOCK_1
+ end
+ end
+ S_FORCE_LOCK_1: begin
+ re_reg <= 0;
+ we_reg <= 0;
+ state <= state + 1; // S_CHK_LOCK
+ end
+ S_CHK_LOCK: begin // Check if lock has been acquired
+ if (rw_ready) begin
+ addr_reg <= 6'h02; // Read STATUSREG[15:0]
+ re_reg <= 1;
+ we_reg <= 0;
+ state <= state + 1; // S_CHK_LOCK_1
+ end
+ end
+ S_CHK_LOCK_1: begin
+ re_reg <= 0;
+ we_reg <= 0;
+ if (rw_nd) begin
+ if (rw_dout[1]) begin
+ state <= S_CF_DETECT_FAIL;
+ end
+ else
+ state <= state - 1; // S_CHK_LOCK
+ end
+ end
+ S_IDLE: begin
+ case (cmd)
+ CMD_IDLE: ready_reg <= 1;
+ CMD_DETECT: begin
+ ready_reg <= 0;
+ rtn_state_CF_detect <= state; // S_IDLE
+ state <= S_CF_DETECT;
+ end
+ CMD_READ: begin
+ ready_reg <= 0;
+ LBA_reg <= LBA;
+ SC_reg <= SC;
+ op_reg <= OP_READ;
+ state <= state + 1; // S_CHK_RDY
+ end
+ CMD_WRITE: begin
+ ready_reg <= 0;
+ LBA_reg <= LBA;
+ SC_reg <= SC;
+ op_reg <= OP_WRITE;
+ state <= state + 1; // S_CHK_RDY
+ end
+ // No default needed
+ endcase
+ end
+
+ /////////////////////////////////////////////////////////
+ //// R/W & Identify
+ /////////////////////////////////////////////////////////
+
+ S_CHK_RDY: begin // Check if the SystemACE controller is ready
+ timeout_cntr <= CMD_RDY_TO_PD;
+ state <= state + 1; // S_CHK_RDY_1
+ end
+ S_CHK_RDY_1: begin
+ if (rw_ready) begin
+ addr_reg <= 6'h02; // Read STATUSREG[15:0]
+ re_reg <= 1;
+ we_reg <= 0;
+ state <= state + 1; // S_CHK_RDY_2
+ end
+ end
+ S_CHK_RDY_2: begin
+ re_reg <= 0;
+ we_reg <= 0;
+ timeout_cntr <= timeout_cntr - 1;
+ if (!timeout_cntr) begin
+ rtn_state_CF_detect <= state - 2; // S_CHK_RDY
+ state <= S_ABORT_CMD;
+ end
+ else if (rw_nd) begin
+ if (rw_dout[8]) begin
+ state <= state + 1; // S_SET_LBA
+ end
+ else begin
+ state <= state - 1; // S_CHK_RDY_1
+ end
+ end
+ end
+ S_SET_LBA: begin // Set Logical Block Address
+ if (rw_ready) begin
+ addr_reg <= 6'h08; // Write MPULBAREG[15:0]
+ rw_din_reg <= (op_reg == OP_IDENTIFY) ? 16'h0000: LBA_reg[15:0];
+ re_reg <= 0;
+ we_reg <= 1;
+ state <= state + 1; // S_SET_LBA_1
+ end
+ end
+ S_SET_LBA_1: begin
+ re_reg <= 0;
+ we_reg <= 0;
+ state <= state + 1; // S_SET_LBA_2
+ end
+ S_SET_LBA_2: begin
+ if (rw_ready) begin
+ addr_reg <= 6'h09; // Write MPULBAREG[31:16]
+ rw_din_reg <= (op_reg == OP_IDENTIFY) ? 16'h0000: {4'h0, LBA_reg[27:16]};
+ re_reg <= 0;
+ we_reg <= 1;
+ state <= state + 1; // S_SET_LBA_3
+ end
+ end
+ S_SET_LBA_3: begin
+ re_reg <= 0;
+ we_reg <= 0;
+ state <= state + 1; // S_SET_SC_CMD
+ end
+ S_SET_SC_CMD: begin // Set sector count & command
+ if (rw_ready) begin
+ addr_reg <= 6'h0A; // Write SECCNTCMDREG[15:0]
+ case (op_reg)
+ OP_IDENTIFY: rw_din_reg <= 16'h0201;
+ OP_READ: rw_din_reg <= {8'h03, SC_reg};
+ OP_WRITE: rw_din_reg <= {8'h04, SC_reg};
+ default: rw_din_reg <= 16'h0001; // if unused, do nothing
+ endcase
+ re_reg <= 0;
+ we_reg <= 1;
+ state <= state + 1; // S_SET_SC_CMD_1
+ end
+ end
+ S_SET_SC_CMD_1: begin
+ re_reg <= 0;
+ we_reg <= 0;
+ state <= state + 1; // S_RESET_CFG
+ end
+ S_RESET_CFG: begin // Reset the Configuration/CompactFlash Controllers
+ if (rw_ready) begin
+ addr_reg <= 6'h0C; // Write CONTROLREG[31:16]
+ rw_din_reg <= 16'h0083;
+ re_reg <= 0;
+ we_reg <= 1;
+ state <= state + 1; // S_RESET_CFG_1
+ end
+ end
+ S_RESET_CFG_1: begin
+ re_reg <= 0;
+ we_reg <= 0;
+ state <= state + 1; // S_INIT_BFR_CNT
+ end
+ S_INIT_BFR_CNT: begin // Initialize the buffer count
+ bfr_cnt <= (op_reg == OP_IDENTIFY) ? 12'h010: {SC_reg, 4'h0};
+ state <= state + 1; // S_CHK_BFR_RDY
+ end
+ S_CHK_BFR_RDY: begin
+ timeout_cntr <= BFR_RDY_TO_PD;
+ state <= state + 1; // S_CHK_BFR_RDY_1
+ end
+ S_CHK_BFR_RDY_1: begin // takes times for buffer ready signal to set
+ state <= state + 1; // S_CHK_BFR_RDY_2
+ end
+ S_CHK_BFR_RDY_2: begin
+ state <= state + 1; // S_CHK_BFR_RDY_3
+ end
+ S_CHK_BFR_RDY_3: begin
+ timeout_cntr <= timeout_cntr - 21'd1;
+ if (systemace_mpbrdy)
+ state <= state + 1; // S_INIT_DATA_CNT;
+ else if (!timeout_cntr) begin
+ rtn_state_CF_detect <= state - 3; // S_CHK_BFR_RDY
+ state <= S_ABORT_CMD;
+ end
+ end
+ S_INIT_DATA_CNT: begin // Initialize data count
+ data_cnt <= 4'hF; // one less than real data count
+ if (op_reg == OP_WRITE) begin
+ state <= S_WR_BFR;
+ we_req_reg <= 1;
+ end
+ else begin
+ addr_reg <= 6'h20; // Read DATABUFREG[15:0]
+ re_reg <= 1;
+ we_reg <= 0;
+ state <= S_RD_BFR;
+ nd_raw_reg <= 0;
+ nd_reg <= 0;
+ end
+ end
+ S_WR_BFR: begin // Write data word to buffer
+ // Assume rw_ready
+ addr_reg <= 6'h20; // Write DATABUFREG[15:0]
+ rw_din_reg <= din;
+ re_reg <= 0;
+ we_reg <= 1;
+ state <= state + 1; // S_WR_BFR_1
+ we_req_reg <= 0;
+ end
+ S_WR_BFR_1: begin
+ data_cnt <= data_cnt - 1;
+ re_reg <= 0;
+ we_reg <= 0;
+ if (!data_cnt) begin
+ bfr_cnt <= bfr_cnt - 1;
+ if (bfr_cnt == 1)
+ state <= S_CLR_RESET_CFG;
+ else
+ state <= S_CHK_BFR_RDY;
+ end
+ else begin
+ state <= state - 1; // S_WR_BFR
+ we_req_reg <= 1;
+ end
+ end
+ S_RD_BFR: begin // Read data word from buffer, set LBA_max if identifying
+ re_reg <= 0;
+ we_reg <= 0;
+ nd_raw_reg <= 0;
+ nd_reg <= 0;
+ if (nd_raw_reg) data_cnt <= data_cnt - 1;
+ if ((op_reg == OP_IDENTIFY) & nd_raw_reg & (bfr_cnt == 13)) begin
+ if (data_cnt == 3) // Word 60
+ LBA_max_reg <= {12'h000, rw_dout};
+ if (data_cnt == 2) // Word 61
+ LBA_max_reg <= {rw_dout[11:0], LBA_max_reg[15:0]};
+ end
+ if (nd_raw_reg & !data_cnt) begin
+ bfr_cnt <= bfr_cnt - 1;
+ if (bfr_cnt == 1)
+ state <= S_CLR_RESET_CFG;
+ else
+ state <= S_CHK_BFR_RDY;
+ end
+ else
+ state <= state + 1; // S_RD_BFR_1
+ end
+ S_RD_BFR_1: begin
+ state <= state + 1; // S_RD_BFR_2
+ end
+ S_RD_BFR_2: begin
+ // Assume rw_ready
+ addr_reg <= 6'h20; // Read DATABUFREG[15:0]
+ re_reg <= 1;
+ we_reg <= 0;
+ state <= state - 2; // S_RD_BFR_1
+ nd_raw_reg <= 1;
+ nd_reg <= (op_reg == OP_READ);
+ end
+ S_CLR_RESET_CFG: begin // Clear Configuration/CompactFlash controller reset
+ if (rw_ready) begin
+ addr_reg <= 6'h0C; // Write CONTROLREG[31:16]
+ rw_din_reg <= 16'h0003;
+ re_reg <= 0;
+ we_reg <= 1;
+ state <= state + 1; // S_RESET_CFG_1
+ end
+ end
+ S_CLR_RESET_CFG_1: begin // Exit subroutine, return to S_IDLE
+ re_reg <= 0;
+ we_reg <= 0;
+ state <= S_IDLE;
+ ready_reg <= 1;
+ CF_detect_reg <= 1;
+ end
+
+ /////////////////////////////////////////////////////////
+ //// Error Handling
+ /////////////////////////////////////////////////////////
+
+ S_ABORT_CMD: begin // Abort current command
+ if (rw_ready) begin