diff options
author | Vasil Zlatanov <v@skozl.com> | 2016-12-12 21:51:10 +0000 |
---|---|---|
committer | Vasil Zlatanov <v@skozl.com> | 2016-12-12 21:51:10 +0000 |
commit | 4b6e0102d20d9ab060ce930e4b846c8be446bb06 (patch) | |
tree | e475eab3716738f2928f0b2063956e9b155f94ab /part_4/mylib | |
download | e2-verilab-4b6e0102d20d9ab060ce930e4b846c8be446bb06.tar.gz e2-verilab-4b6e0102d20d9ab060ce930e4b846c8be446bb06.tar.bz2 e2-verilab-4b6e0102d20d9ab060ce930e4b846c8be446bb06.zip |
public push
Diffstat (limited to 'part_4/mylib')
-rw-r--r-- | part_4/mylib/add3_ge5.v | 31 | ||||
-rw-r--r-- | part_4/mylib/bin2bcd_16.v | 109 | ||||
-rw-r--r-- | part_4/mylib/clktick_16.v | 42 | ||||
-rw-r--r-- | part_4/mylib/counter_13.v | 24 | ||||
-rw-r--r-- | part_4/mylib/hex_to_7seg.v | 38 | ||||
-rw-r--r-- | part_4/mylib/multiply_4.v | 107 | ||||
-rw-r--r-- | part_4/mylib/multiply_k.v | 107 | ||||
-rw-r--r-- | part_4/mylib/pulse_gen.v | 43 | ||||
-rw-r--r-- | part_4/mylib/pwm.v | 25 | ||||
-rw-r--r-- | part_4/mylib/spi2adc.v | 157 | ||||
-rw-r--r-- | part_4/mylib/spi2dac.v | 135 |
11 files changed, 818 insertions, 0 deletions
diff --git a/part_4/mylib/add3_ge5.v b/part_4/mylib/add3_ge5.v new file mode 100644 index 0000000..0daf78a --- /dev/null +++ b/part_4/mylib/add3_ge5.v @@ -0,0 +1,31 @@ +//------------------------------
+// Module name: add3_ge5
+// Function: Add 3 to input if it is 5 or above
+// Creator: Peter Cheung
+// Version: 1.0
+// Date: 21 Jan 2014
+//------------------------------
+
+module add3_ge5(w,a);
+ input [3:0] w;
+ output [3:0] a;
+ reg [3:0] a;
+
+ always @ (w)
+ case (w)
+ 4'b0000: a <= 4'b0000;
+ 4'b0001: a <= 4'b0001;
+ 4'b0010: a <= 4'b0010;
+ 4'b0011: a <= 4'b0011;
+ 4'b0100: a <= 4'b0100;
+ 4'b0101: a <= 4'b1000;
+ 4'b0110: a <= 4'b1001;
+ 4'b0111: a <= 4'b1010;
+ 4'b1000: a <= 4'b1011;
+ 4'b1001: a <= 4'b1100;
+ 4'b1010: a <= 4'b1101;
+ 4'b1011: a <= 4'b1110;
+ 4'b1100: a <= 4'b1111;
+ default: a <= 4'b0000; // a cannot be 13 or larger, else overflow
+ endcase
+endmodule
\ No newline at end of file diff --git a/part_4/mylib/bin2bcd_16.v b/part_4/mylib/bin2bcd_16.v new file mode 100644 index 0000000..b25d0bd --- /dev/null +++ b/part_4/mylib/bin2bcd_16.v @@ -0,0 +1,109 @@ +//------------------------------
+// Module name: bin2bcd_16
+// Function: Converts a 16-bit binary number to 5 digits BCD
+// .... it uses a shift-and-add3 algorithm
+// Creator: Peter Cheung
+// Version: 2.0 (Correct mistake - problem with numbers 0x5000 or larger)
+// Date: 24 Nov 2016
+//------------------------------
+// For more explanation of how this work, see
+// ... instructions on wwww.ee.ic.ac.uk/pcheung/teaching/E2_experiment
+
+module bin2bcd_16 (B, BCD_0, BCD_1, BCD_2, BCD_3, BCD_4);
+
+ input [15:0] B; // binary input number
+ output [3:0] BCD_0, BCD_1, BCD_2, BCD_3, BCD_4; // BCD digit LSD to MSD
+
+ wire [3:0] w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13;
+ wire [3:0] w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25;
+ wire [3:0] w26,w27,w28,w29,w30,w31,w32,w33,w34,w35;
+ wire [3:0] a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13;
+ wire [3:0] a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25;
+ wire [3:0] a26,a27,a28,a29,a30,a31,a32,a33,a34,a35;
+
+ // Instantiate a tree of add3-if-greater than or equal to 5 cells
+ // ... input is w_n, and output is a_n
+ add3_ge5 A1 (w1,a1);
+ add3_ge5 A2 (w2,a2);
+ add3_ge5 A3 (w3,a3);
+ add3_ge5 A4 (w4,a4);
+ add3_ge5 A5 (w5,a5);
+ add3_ge5 A6 (w6,a6);
+ add3_ge5 A7 (w7,a7);
+ add3_ge5 A8 (w8,a8);
+ add3_ge5 A9 (w9,a9);
+ add3_ge5 A10 (w10,a10);
+ add3_ge5 A11 (w11,a11);
+ add3_ge5 A12 (w12,a12);
+ add3_ge5 A13 (w13,a13);
+ add3_ge5 A14 (w14,a14);
+ add3_ge5 A15 (w15,a15);
+ add3_ge5 A16 (w16,a16);
+ add3_ge5 A17 (w17,a17);
+ add3_ge5 A18 (w18,a18);
+ add3_ge5 A19 (w19,a19);
+ add3_ge5 A20 (w20,a20);
+ add3_ge5 A21 (w21,a21);
+ add3_ge5 A22 (w22,a22);
+ add3_ge5 A23 (w23,a23);
+ add3_ge5 A24 (w24,a24);
+ add3_ge5 A25 (w25,a25);
+ add3_ge5 A26 (w26,a26);
+ add3_ge5 A27 (w27,a27);
+ add3_ge5 A28 (w28,a28);
+ add3_ge5 A29 (w29,a29);
+ add3_ge5 A30 (w30,a30);
+ add3_ge5 A31 (w31,a31);
+ add3_ge5 A32 (w32,a32);
+ add3_ge5 A33 (w33,a33);
+ add3_ge5 A34 (w34,a34);
+ add3_ge5 A35 (w35,a35);
+
+ // wire the tree of add3 modules together
+ assign w1 = {1'b0,B[15:13]}; // w_n is the input port to module a_n
+ assign w2 = {a1[2:0], B[12]};
+ assign w3 = {a2[2:0], B[11]};
+ assign w4 = {1'b0,a1[3],a2[3],a3[3]};
+ assign w5 = {a3[2:0], B[10]};
+ assign w6 = {a4[2:0], a5[3]};
+ assign w7 = {a5[2:0], B[9]};
+ assign w8 = {a6[2:0], a7[3]};
+ assign w9 = {a7[2:0], B[8]};
+ assign w10 = {1'b0, a4[3], a6[3], a8[3]};
+ assign w11 = {a8[2:0], a9[3]};
+ assign w12 = {a9[2:0], B[7]};
+ assign w13 = {a10[2:0], a11[3]};
+ assign w14 = {a11[2:0], a12[3]};
+ assign w15 = {a12[2:0], B[6]};
+ assign w16 = {a13[2:0], a14[3]};
+ assign w17 = {a14[2:0], a15[3]};
+ assign w18 = {a15[2:0], B[5]};
+ assign w19 = {1'b0, a10[3], a13[3], a16[3]};
+ assign w20 = {a16[2:0], a17[3]};
+ assign w21 = {a17[2:0], a18[3]};
+ assign w22 = {a18[2:0], B[4]};
+ assign w23 = {a19[2:0], a20[3]};
+ assign w24 = {a20[2:0], a21[3]};
+ assign w25 = {a21[2:0], a22[3]};
+ assign w26 = {a22[2:0], B[3]};
+ assign w27 = {a23[2:0], a24[3]};
+ assign w28 = {a24[2:0], a25[3]};
+ assign w29 = {a25[2:0], a26[3]};
+ assign w30 = {a26[2:0], B[2]};
+ assign w31 = {1'b0,a19[3], a23[3], a27[3]};
+ assign w32 = {a27[2:0], a28[3]};
+ assign w33 = {a28[2:0], a29[3]};
+ assign w34 = {a29[2:0], a30[3]};
+ assign w35 = {a30[2:0], B[1]};
+
+ // connect up to four BCD digit outputs
+ assign BCD_0 = {a35[2:0],B[0]};
+ assign BCD_1 = {a34[2:0],a35[3]};
+ assign BCD_2 = {a33[2:0],a34[3]};
+ assign BCD_3 = {a32[2:0],a33[3]};
+ assign BCD_4 = {a31[2:0],a32[3]};
+endmodule
+
+
+
+
diff --git a/part_4/mylib/clktick_16.v b/part_4/mylib/clktick_16.v new file mode 100644 index 0000000..e6b99eb --- /dev/null +++ b/part_4/mylib/clktick_16.v @@ -0,0 +1,42 @@ +// Design Name : clktick_16
+// File Name : clktick.v
+// Function : divide an input clock signal by n+1
+//-----------------------------------------------------
+
+module clktick_16 (
+ clkin, // Clock input to the design
+ enable, // enable clk divider
+ N, // Clock division factor is N+1
+ tick // pulse_out goes high for one cycle (n+1) clock cycles
+); // End of port list
+
+parameter N_BIT = 16;
+//-------------Input Ports-----------------------------
+input clkin;
+input enable;
+input [N_BIT-1:0] N;
+
+//-------------Output Ports----------------------------
+output tick;
+
+//-------------Output Ports Data Type------------------
+// Output port can be a storage element (reg) or a wire
+reg [N_BIT-1:0] count;
+reg tick;
+
+initial tick = 1'b0;
+
+//------------ Main Body of the module ------------------------
+
+ always @ (posedge clkin)
+ if (enable == 1'b1)
+ if (count == 0) begin
+ tick <= 1'b1;
+ count <= N;
+ end
+ else begin
+ tick <= 1'b0;
+ count <= count - 1'b1;
+ end
+
+endmodule // End of Module clktick
\ No newline at end of file diff --git a/part_4/mylib/counter_13.v b/part_4/mylib/counter_13.v new file mode 100644 index 0000000..59ad089 --- /dev/null +++ b/part_4/mylib/counter_13.v @@ -0,0 +1,24 @@ +`timescale 1ns / 100ps
+
+module counter_13 (
+ clock,
+ enable,
+ count,
+ reset
+ );
+
+ parameter BIT_SZ = 13;
+ input clock;
+ input enable;
+ input reset;
+ output reg [BIT_SZ-1:0] count;
+
+
+ initial count = 0;
+
+ always @ (posedge clock)
+ if (reset == 1'b0)
+ count <= 0;
+ else if (enable == 1'b0)
+ count <= count + 1'b1;
+endmodule
diff --git a/part_4/mylib/hex_to_7seg.v b/part_4/mylib/hex_to_7seg.v new file mode 100644 index 0000000..1c39f02 --- /dev/null +++ b/part_4/mylib/hex_to_7seg.v @@ -0,0 +1,38 @@ +//------------------------------
+// Module name: hex_to_7seg
+// Function: convert 4-bit hex value to drive 7 segment display
+// output is low active - using case statement
+// Creator: Peter Cheung
+// Version: 1.1
+// Date: 23 Oct 2011
+//------------------------------
+
+module hex_to_7seg (out,in);
+
+ output [6:0] out; // low-active output to drive 7 segment display
+ input [3:0] in; // 4-bit binary input of a hexademical number
+
+ reg [6:0] out; // make out a variable for use in procedural assignment
+
+ always @ (in)
+ case (in)
+ 4'h0: out = 7'b1000000;
+ 4'h1: out = 7'b1111001; // -- 0 ---
+ 4'h2: out = 7'b0100100; // | |
+ 4'h3: out = 7'b0110000; // 5 1
+ 4'h4: out = 7'b0011001; // | |
+ 4'h5: out = 7'b0010010; // -- 6 ---
+ 4'h6: out = 7'b0000010; // | |
+ 4'h7: out = 7'b1111000; // 4 2
+ 4'h8: out = 7'b0000000; // | |
+ 4'h9: out = 7'b0011000; // -- 3 ---
+ 4'ha: out = 7'b0001000;
+ 4'hb: out = 7'b0000011;
+ 4'hc: out = 7'b1000110;
+ 4'hd: out = 7'b0100001;
+ 4'he: out = 7'b0000110;
+ 4'hf: out = 7'b0001110;
+ endcase
+endmodule
+
+
diff --git a/part_4/mylib/multiply_4.v b/part_4/mylib/multiply_4.v new file mode 100644 index 0000000..863b6c1 --- /dev/null +++ b/part_4/mylib/multiply_4.v @@ -0,0 +1,107 @@ +// megafunction wizard: %LPM_MULT%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: lpm_mult
+
+// ============================================================
+// File Name: multiply_k.v
+// Megafunction Name(s):
+// lpm_mult
+//
+// Simulation Library Files(s):
+// lpm
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 13.1.0 Build 162 10/23/2013 SJ Web Edition
+// ************************************************************
+
+
+//Copyright (C) 1991-2013 Altera Corporation
+//Your use of Altera Corporation's design tools, logic functions
+//and other software and tools, and its AMPP partner logic
+//functions, and any output files from any of the foregoing
+//(including device programming or simulation files), and any
+//associated documentation or information are expressly subject
+//to the terms and conditions of the Altera Program License
+//Subscription Agreement, Altera MegaCore Function License
+//Agreement, or other applicable license agreement, including,
+//without limitation, that your use is for the sole purpose of
+//programming logic devices manufactured by Altera and sold by
+//Altera or its authorized distributors. Please refer to the
+//applicable agreement for further details.
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module multiply_4 (
+ dataa,
+ result);
+
+ input [8:0] dataa;
+ output [19:0] result;
+
+ wire [19:0] sub_wire0;
+ wire [10:0] sub_wire1 = 11'h4;
+ wire [19:0] result = sub_wire0[19:0];
+
+ lpm_mult lpm_mult_component (
+ .dataa (dataa),
+ .datab (sub_wire1),
+ .result (sub_wire0),
+ .aclr (1'b0),
+ .clken (1'b1),
+ .clock (1'b0),
+ .sum (1'b0));
+ defparam
+ lpm_mult_component.lpm_hint = "INPUT_B_IS_CONSTANT=YES,MAXIMIZE_SPEED=5",
+ lpm_mult_component.lpm_representation = "UNSIGNED",
+ lpm_mult_component.lpm_type = "LPM_MULT",
+ lpm_mult_component.lpm_widtha = 9,
+ lpm_mult_component.lpm_widthb = 11,
+ lpm_mult_component.lpm_widthp = 20;
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: AutoSizeResult NUMERIC "1"
+// Retrieval info: PRIVATE: B_isConstant NUMERIC "1"
+// Retrieval info: PRIVATE: ConstantB NUMERIC "1638"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
+// Retrieval info: PRIVATE: LPM_PIPELINE NUMERIC "0"
+// Retrieval info: PRIVATE: Latency NUMERIC "0"
+// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
+// Retrieval info: PRIVATE: SignedMult NUMERIC "0"
+// Retrieval info: PRIVATE: USE_MULT NUMERIC "1"
+// Retrieval info: PRIVATE: ValidConstant NUMERIC "1"
+// Retrieval info: PRIVATE: WidthA NUMERIC "9"
+// Retrieval info: PRIVATE: WidthB NUMERIC "11"
+// Retrieval info: PRIVATE: WidthP NUMERIC "20"
+// Retrieval info: PRIVATE: aclr NUMERIC "0"
+// Retrieval info: PRIVATE: clken NUMERIC "0"
+// Retrieval info: PRIVATE: new_diagram STRING "1"
+// Retrieval info: PRIVATE: optimize NUMERIC "0"
+// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
+// Retrieval info: CONSTANT: LPM_HINT STRING "INPUT_B_IS_CONSTANT=YES,MAXIMIZE_SPEED=5"
+// Retrieval info: CONSTANT: LPM_REPRESENTATION STRING "UNSIGNED"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_MULT"
+// Retrieval info: CONSTANT: LPM_WIDTHA NUMERIC "9"
+// Retrieval info: CONSTANT: LPM_WIDTHB NUMERIC "11"
+// Retrieval info: CONSTANT: LPM_WIDTHP NUMERIC "20"
+// Retrieval info: USED_PORT: dataa 0 0 9 0 INPUT NODEFVAL "dataa[8..0]"
+// Retrieval info: USED_PORT: result 0 0 20 0 OUTPUT NODEFVAL "result[19..0]"
+// Retrieval info: CONNECT: @dataa 0 0 9 0 dataa 0 0 9 0
+// Retrieval info: CONNECT: @datab 0 0 11 0 1638 0 0 11 0
+// Retrieval info: CONNECT: result 0 0 20 0 @result 0 0 20 0
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k.bsf FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k_inst.v FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k_bb.v TRUE
+// Retrieval info: LIB_FILE: lpm
diff --git a/part_4/mylib/multiply_k.v b/part_4/mylib/multiply_k.v new file mode 100644 index 0000000..8292b58 --- /dev/null +++ b/part_4/mylib/multiply_k.v @@ -0,0 +1,107 @@ +// megafunction wizard: %LPM_MULT%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: lpm_mult
+
+// ============================================================
+// File Name: multiply_k.v
+// Megafunction Name(s):
+// lpm_mult
+//
+// Simulation Library Files(s):
+// lpm
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 13.1.0 Build 162 10/23/2013 SJ Web Edition
+// ************************************************************
+
+
+//Copyright (C) 1991-2013 Altera Corporation
+//Your use of Altera Corporation's design tools, logic functions
+//and other software and tools, and its AMPP partner logic
+//functions, and any output files from any of the foregoing
+//(including device programming or simulation files), and any
+//associated documentation or information are expressly subject
+//to the terms and conditions of the Altera Program License
+//Subscription Agreement, Altera MegaCore Function License
+//Agreement, or other applicable license agreement, including,
+//without limitation, that your use is for the sole purpose of
+//programming logic devices manufactured by Altera and sold by
+//Altera or its authorized distributors. Please refer to the
+//applicable agreement for further details.
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module multiply_k (
+ dataa,
+ result);
+
+ input [8:0] dataa;
+ output [19:0] result;
+
+ wire [19:0] sub_wire0;
+ wire [10:0] sub_wire1 = 11'h666;
+ wire [19:0] result = sub_wire0[19:0];
+
+ lpm_mult lpm_mult_component (
+ .dataa (dataa),
+ .datab (sub_wire1),
+ .result (sub_wire0),
+ .aclr (1'b0),
+ .clken (1'b1),
+ .clock (1'b0),
+ .sum (1'b0));
+ defparam
+ lpm_mult_component.lpm_hint = "INPUT_B_IS_CONSTANT=YES,MAXIMIZE_SPEED=5",
+ lpm_mult_component.lpm_representation = "UNSIGNED",
+ lpm_mult_component.lpm_type = "LPM_MULT",
+ lpm_mult_component.lpm_widtha = 9,
+ lpm_mult_component.lpm_widthb = 11,
+ lpm_mult_component.lpm_widthp = 20;
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: AutoSizeResult NUMERIC "1"
+// Retrieval info: PRIVATE: B_isConstant NUMERIC "1"
+// Retrieval info: PRIVATE: ConstantB NUMERIC "1638"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
+// Retrieval info: PRIVATE: LPM_PIPELINE NUMERIC "0"
+// Retrieval info: PRIVATE: Latency NUMERIC "0"
+// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
+// Retrieval info: PRIVATE: SignedMult NUMERIC "0"
+// Retrieval info: PRIVATE: USE_MULT NUMERIC "1"
+// Retrieval info: PRIVATE: ValidConstant NUMERIC "1"
+// Retrieval info: PRIVATE: WidthA NUMERIC "9"
+// Retrieval info: PRIVATE: WidthB NUMERIC "11"
+// Retrieval info: PRIVATE: WidthP NUMERIC "20"
+// Retrieval info: PRIVATE: aclr NUMERIC "0"
+// Retrieval info: PRIVATE: clken NUMERIC "0"
+// Retrieval info: PRIVATE: new_diagram STRING "1"
+// Retrieval info: PRIVATE: optimize NUMERIC "0"
+// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
+// Retrieval info: CONSTANT: LPM_HINT STRING "INPUT_B_IS_CONSTANT=YES,MAXIMIZE_SPEED=5"
+// Retrieval info: CONSTANT: LPM_REPRESENTATION STRING "UNSIGNED"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_MULT"
+// Retrieval info: CONSTANT: LPM_WIDTHA NUMERIC "9"
+// Retrieval info: CONSTANT: LPM_WIDTHB NUMERIC "11"
+// Retrieval info: CONSTANT: LPM_WIDTHP NUMERIC "20"
+// Retrieval info: USED_PORT: dataa 0 0 9 0 INPUT NODEFVAL "dataa[8..0]"
+// Retrieval info: USED_PORT: result 0 0 20 0 OUTPUT NODEFVAL "result[19..0]"
+// Retrieval info: CONNECT: @dataa 0 0 9 0 dataa 0 0 9 0
+// Retrieval info: CONNECT: @datab 0 0 11 0 1638 0 0 11 0
+// Retrieval info: CONNECT: result 0 0 20 0 @result 0 0 20 0
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k.bsf FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k_inst.v FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL multiply_k_bb.v TRUE
+// Retrieval info: LIB_FILE: lpm
diff --git a/part_4/mylib/pulse_gen.v b/part_4/mylib/pulse_gen.v new file mode 100644 index 0000000..d82fe49 --- /dev/null +++ b/part_4/mylib/pulse_gen.v @@ -0,0 +1,43 @@ +//------------------------------
+// Module name: pulse_gen (Moore)
+// Function: Generate one clock pulse on +ve edge of input
+// Creator: Peter Cheung
+// Version: 1.0
+// Date: 29 Jan 2014
+//------------------------------
+
+module pulse_gen(pulse, in, clk);
+
+ output pulse; // output pulse lasting one clk cycle
+ input in; // input, +ve edge to be detected
+ input clk; // clock signal
+
+ reg [1:0] state;
+ reg pulse;
+
+ parameter IDLE = 2'b0; // state coding for IDLE state
+ parameter IN_HIGH = 2'b01;
+ parameter WAIT_LOW = 2'b10;
+
+ initial state = IDLE;
+
+ always @ (posedge clk)
+ begin
+ pulse <= 0; // default output
+ case (state)
+ IDLE: if (in == 1'b1) begin
+ state <= IN_HIGH; pulse <= 1'b1; end
+ else
+ state <= IDLE;
+ IN_HIGH: if (in == 1'b1)
+ state <= WAIT_LOW;
+ else
+ state <= IDLE;
+ WAIT_LOW: if (in == 1'b1)
+ state <= WAIT_LOW;
+ else
+ state <= IDLE;
+ default: ;
+ endcase
+ end //... always
+endmodule
diff --git a/part_4/mylib/pwm.v b/part_4/mylib/pwm.v new file mode 100644 index 0000000..c3b34d9 --- /dev/null +++ b/part_4/mylib/pwm.v @@ -0,0 +1,25 @@ +module pwm (clk, data_in, load, pwm_out);
+
+ input clk; // system clock
+ input [9:0] data_in; // input data for conversion
+ input load; // high pulse to load new data
+ output pwm_out; // PWM output
+
+ reg [9:0] d; // internal register
+ reg [9:0] count; // internal 10-bit counter
+ reg pwm_out;
+
+ always @ (posedge clk)
+ if (load == 1'b1) d <= data_in;
+
+ initial count = 10'b0;
+
+ always @ (posedge clk) begin
+ count <= count + 1'b1;
+ if (count > d)
+ pwm_out <= 1'b0;
+ else
+ pwm_out <= 1'b1;
+ end
+
+endmodule
diff --git a/part_4/mylib/spi2adc.v b/part_4/mylib/spi2adc.v new file mode 100644 index 0000000..41be7ad --- /dev/null +++ b/part_4/mylib/spi2adc.v @@ -0,0 +1,157 @@ +//------------------------------
+// Module name: spi2adc
+// Function: SPI interface for MCP3002 ADC
+// Creator: Peter Cheung
+// Version: 3.0
+// Date: 8 Dec 2016
+//------------------------------
+
+module spi2adc (sysclk, start, channel, data_from_adc, data_valid,
+ sdata_to_adc, adc_cs, adc_sck, sdata_from_adc);
+
+ input sysclk; // 50MHz system clock of DE0
+ input start; // Pulse to start ADC, minimum wide = clock period
+ input channel; // channel 0 or 1 to be converted
+ output [9:0] data_from_adc; // 10-bit ADC result
+ output data_valid; // High indicates that converted data valid
+ output sdata_to_adc; // Serial commands send to adc chip
+ output adc_cs; // chip select - low when converting
+ output adc_sck; // SPI clock - active during conversion
+ input sdata_from_adc; // Converted serial data from ADC, MSB first
+
+//-------------Input Ports-----------------------------
+// All the input ports should be wires
+ wire sysclk, start, sdata_from_adc;
+
+//-------------Output Ports-----------------------------
+// Output port can be a storage element (reg) or a wire
+ reg [9:0] data_from_adc;
+ reg adc_cs;
+ wire sdata_to_adc, adc_sck, data_valid;
+
+//-------------Configuration parameters for ADC --------
+ parameter SGL=1'b1; // 0:diff i/p, 1:single-ended
+ parameter MSBF=1'b1; // 0:LSB first, 1:MSB first
+
+// --- Submodule: Generate internal clock at 1 MHz -----
+ reg clk_1MHz; // 1Mhz clock derived from 50MHz
+ reg [4:0] ctr; // internal counter
+ reg tick; // 1MHz clock tick lasting 20ns, i.e. one 50MHz cycle
+ parameter TIME_CONSTANT = 5'd24; // change this for diff clk freq
+ initial begin
+ clk_1MHz = 0; // don't need to reset - don't care if it is 1 or 0 to start
+ ctr = 5'b0; // ... to start. Initialise to make simulation easier
+ tick = 1'b0;
+ end
+
+ always @ (posedge sysclk) //
+ if (ctr==0) begin
+ ctr <= TIME_CONSTANT;
+ if (clk_1MHz==1'b0)
+ tick <= 1'b1;
+ clk_1MHz <= ~clk_1MHz; // toggle the output clock for squarewave
+ end
+ else begin
+ ctr <= ctr - 1'b1;
+ tick <= 1'b0;
+ end
+// ---- end internal clock generator ----------
+
+// ---- Detect start is asserted with a small state machine
+ // .... FF set on positive edge of start
+ // .... reset when adc_cs goes high again
+ reg [1:0] sr_state;
+ parameter IDLE = 2'b00,WAIT_CSB_FALL = 2'b01, WAIT_CSB_HIGH = 2'b10;
+ reg adc_start;
+
+ initial begin
+ sr_state = IDLE;
+ adc_start = 1'b0; // set while sending data to ADC
+ end
+
+ always @ (posedge sysclk)
+ case (sr_state)
+ IDLE: if (start==1'b0) sr_state <= IDLE;
+ else begin
+ sr_state <= WAIT_CSB_FALL;
+ adc_start <= 1'b1;
+ end
+ WAIT_CSB_FALL: if (adc_cs==1'b1) sr_state <= WAIT_CSB_FALL;
+ else sr_state <= WAIT_CSB_HIGH;
+
+ WAIT_CSB_HIGH: if (adc_cs==1'b0) sr_state <= WAIT_CSB_HIGH;
+ else begin
+ sr_state <= IDLE;
+ adc_start <= 1'b0;
+ end
+ default: sr_state <= IDLE;
+ endcase
+//------- End circuit to detect start and end of conversion
+
+
+// spi controller designed as a state machine
+// .... with 16 states (idle, and S1-S15 indicated by state value
+
+ reg [4:0] state;
+ reg adc_done, adc_din, shift_ena;
+
+ initial begin
+ state = 5'b0; adc_cs = 1'b1; adc_done = 1'b0;
+ adc_din = 1'b0; shift_ena <= 1'b0;
+ end
+
+ always @(posedge sysclk)
+ if (tick==1'b1) begin
+
+ // default outputs and state transition
+ adc_cs <= 1'b0; adc_done <= 1'b0; adc_din <= 1'b0; shift_ena <= 1'b0;
+ state <= state + 1'b1;
+ case (state)
+ 5'd0: begin
+ if (adc_start==1'b0) begin
+ state <= 5'd0; // still idle
+ adc_cs <= 1'b1; // chip select not active
+ end
+ else begin
+ state <= 5'd1; // start converting
+ adc_din <= 1'b1; // start bit is 1
+ end
+ end
+ 5'd1: adc_din <= SGL; // SGL bit
+ 5'd2: adc_din <= channel; // CH bit
+ 5'd3: adc_din <= MSBF; // MSB first bit
+ 5'd4: shift_ena <= 1'b1; // start shifting data from adc
+ 5'd15: begin
+ shift_ena <= 1'b0;
+ adc_done <= 1'b1;
+ end
+ 5'd16: begin
+ adc_cs <= 1'b1; // last state - disable chip select
+ state <= 5'd0; // go back to idle state
+ end
+ default:
+ shift_ena <= 1'b1; // unspecified states are covered by default above
+ endcase
+ end // ... always
+
+ // shift register for output data
+ reg [9:0] shift_reg;
+ initial begin
+ shift_reg = 10'b0;
+ data_from_adc = 10'b0;
+ end
+
+ always @(negedge sysclk)
+ if((adc_cs==1'b0)&&(shift_ena==1'b1)&&(tick==1'b1)) // start shifting data_in
+ shift_reg <= {shift_reg[8:0],sdata_from_adc};
+
+ // Latch converted output data
+ always @(posedge sysclk)
+ if(adc_done)
+ data_from_adc = shift_reg;
+
+ // Assign outputs to drive SPI interface to DAC
+ assign adc_sck = !clk_1MHz & !adc_cs;
+ assign sdata_to_adc = adc_din;
+ assign data_valid = adc_cs;
+endmodule
\ No newline at end of file diff --git a/part_4/mylib/spi2dac.v b/part_4/mylib/spi2dac.v new file mode 100644 index 0000000..6b8bbbd --- /dev/null +++ b/part_4/mylib/spi2dac.v @@ -0,0 +1,135 @@ +//------------------------------
+// Module name: spi2dac
+// Function: SPI interface for MPC4911 DAC
+// Creator: Peter Cheung
+// Version: 3.0
+// Date: 8 Dec 2016
+//------------------------------
+
+module spi2dac (sysclk, data_in, load, dac_sdi, dac_cs, dac_sck, dac_ld);
+
+ input sysclk; // 50MHz system clock of DE1
+ input [9:0] data_in; // input data to DAC
+ input load; // Pulse to load data to dac
+ output dac_sdi; // SPI serial data out
+ output dac_cs; // chip select - low when sending data to dac
+ output dac_sck; // SPI clock, 16 cycles at half sysclk freq
+ output dac_ld;
+
+//-------------Input Ports-----------------------------
+// All the input ports should be wires
+ wire sysclk, load;
+ wire [9:0] data_in;
+
+//-------------Output Ports-----------------------------
+// Output port can be a storage element (reg) or a wire
+ reg dac_cs, dac_ld;
+ wire dac_sck, dac_sdi;
+
+ parameter BUF=1'b1; // 0:no buffer, 1:Vref buffered
+ parameter GA_N=1'b1; // 0:gain = 2x, 1:gain = 1x
+ parameter SHDN_N=1'b1; // 0:power down, 1:dac active
+
+ wire [3:0] cmd = {1'b0,BUF,GA_N,SHDN_N}; // wire to VDD or GND
+
+ // --- internal 1MHz symmetical clock generator -----
+ reg clk_1MHz; // 1Mhz clock derived from 50MHz
+ reg [4:0] ctr; // internal counter
+ reg tick; // 1MHz clock tick (1 cycle of 20ns every 1 usec)
+
+ parameter TC = 5'd24; // Terminal count - change this for diff clk freq
+ initial begin
+ clk_1MHz = 0; // don't need to reset - don't care if it is 1 or 0 to start
+ ctr = 5'b0; // ... Initialise when FPGA is configured
+ tick = 1'b0;
+ end
+
+ always @ (posedge sysclk)
+ if (ctr==0) begin
+ ctr <= TC;
+ if (clk_1MHz==1'b0)
+ tick <= 1'b1;
+ clk_1MHz <= ~clk_1MHz; // toggle the output clock for squarewave
+ end
+ else begin
+ ctr <= ctr - 1'b1;
+ tick <= 1'b0;
+ end
+ // ---- end internal 1MHz symmetical clock generator ----------
+
+ // ---- FSM to detect rising edge of load and falling edge of dac_cs
+ // .... sr_state set on posedge of load
+ // .... sr_state reset when dac_cs goes high at the end of DAC output cycle
+ reg [1:0] sr_state;
+ parameter IDLE = 2'b00,WAIT_CSB_FALL = 2'b01, WAIT_CSB_HIGH = 2'b10;
+ reg dac_start; // set if a DAC write is detected
+
+ initial begin
+ sr_state = IDLE;
+ dac_start = 1'b0; // set while sending data to DAC
+ end
+
+ always @ (posedge sysclk) // state transition
+ case (sr_state)
+ IDLE: if (load==1'b1) sr_state <= WAIT_CSB_FALL;
+ WAIT_CSB_FALL: if (dac_cs==1'b0) sr_state <= WAIT_CSB_HIGH;
+ WAIT_CSB_HIGH: if (dac_cs==1'b1) sr_state <= IDLE;
+ default: sr_state <= IDLE;
+ endcase
+
+ always @ (*)
+ case (sr_state)
+ IDLE: dac_start = 1'b0;
+ WAIT_CSB_FALL: dac_start = 1'b1;
+ WAIT_CSB_HIGH: dac_start = 1'b0;
+ default: dac_start = 1'b0;
+ endcase
+
+ //------- End circuit to detect start and end of conversion state machine
+
+ //------- spi controller FSM
+ // .... with 17 states (idle, and S1-S16
+ // .... for the 16 cycles each sending 1-bit to dac)
+ reg [4:0] state;
+
+ initial begin
+ state = 5'b0; dac_ld = 1'b0; dac_cs = 1'b1;
+ end
+
+ always @(posedge sysclk) // FSM state transition
+ if (tick==1'b1)
+ case (state)
+ 5'd0: if (dac_start == 1'b1) // waiting to start
+ state <= state + 1'b1;
+ else
+ state <= 5'b0;
+ 5'd17: state <= 5'd0; // go back to idle state
+ default: state <= state + 1'b1; // default go to next state
+ endcase
+
+ always @ (*) begin // FSM output
+ dac_cs = 1'b0; dac_ld = 1'b1;
+ case (state)
+ 5'd0: dac_cs = 1'b1;
+ 5'd17: begin dac_cs = 1'b1; dac_ld = 1'b0; end
+ default: begin dac_cs = 1'b0; dac_ld = 1'b1; end
+ endcase
+ end //always
+ // --------- END of spi controller FSM
+
+ // shift register for output data
+ reg [15:0] shift_reg;
+ initial begin
+ shift_reg = 16'b0;
+ end
+
+ always @(posedge sysclk)
+ if((dac_start==1'b1)&&(dac_cs==1'b1)&&(tick==1'b1)) // parallel load data to shift reg
+ shift_reg <= {cmd,data_in,2'b00};
+ else if (tick==1'b1) // .. else start shifting
+ shift_reg <= {shift_reg[14:0],1'b0};
+
+ // Assign outputs to drive SPI interface to DAC
+ assign dac_sck = !clk_1MHz&!dac_cs;
+ assign dac_sdi = shift_reg[15];
+endmodule
\ No newline at end of file |