From 81337eb41dca51fcdba7572b0449927732f4f3b5 Mon Sep 17 00:00:00 2001 From: zedarider Date: Thu, 1 Dec 2016 23:57:19 +0000 Subject: adding part 2 and 3 --- part_3/mylib/ROM.v | 160 +++++++++++++++++++++++++++++++++++++++++++++ part_3/mylib/counter_10.v | 18 +++++ part_3/mylib/hex_to_7seg.v | 27 ++++++++ part_3/mylib/pwm.v | 25 +++++++ part_3/mylib/spi2adc.v | 150 ++++++++++++++++++++++++++++++++++++++++++ part_3/mylib/spi2dac.v | 128 ++++++++++++++++++++++++++++++++++++ part_3/mylib/tick_5000.v | 32 +++++++++ 7 files changed, 540 insertions(+) create mode 100755 part_3/mylib/ROM.v create mode 100755 part_3/mylib/counter_10.v create mode 100755 part_3/mylib/hex_to_7seg.v create mode 100755 part_3/mylib/pwm.v create mode 100755 part_3/mylib/spi2adc.v create mode 100755 part_3/mylib/spi2dac.v create mode 100755 part_3/mylib/tick_5000.v (limited to 'part_3/mylib') diff --git a/part_3/mylib/ROM.v b/part_3/mylib/ROM.v new file mode 100755 index 0000000..296e57c --- /dev/null +++ b/part_3/mylib/ROM.v @@ -0,0 +1,160 @@ +// megafunction wizard: %ROM: 1-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: ROM.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 16.0.0 Build 211 04/27/2016 SJ Standard Edition +// ************************************************************ + + +//Copyright (C) 1991-2016 Altera Corporation. All rights reserved. +//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, the Altera Quartus Prime License Agreement, +//the 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 ROM ( + address, + clock, + q); + + input [9:0] address; + input clock; + output [9:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [9:0] sub_wire0; + wire [9:0] q = sub_wire0[9:0]; + + altsyncram altsyncram_component ( + .address_a (address), + .clock0 (clock), + .q_a (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .address_b (1'b1), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_a ({10{1'b1}}), + .data_b (1'b1), + .eccstatus (), + .q_b (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_a (1'b0), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_a = "NONE", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_output_a = "BYPASS", + altsyncram_component.init_file = "./rom_data/rom_data.mif", + altsyncram_component.intended_device_family = "Cyclone V", + altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 1024, + altsyncram_component.operation_mode = "ROM", + altsyncram_component.outdata_aclr_a = "NONE", + altsyncram_component.outdata_reg_a = "CLOCK0", + altsyncram_component.widthad_a = 10, + altsyncram_component.width_a = 10, + altsyncram_component.width_byteena_a = 1; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: AclrAddr NUMERIC "0" +// Retrieval info: PRIVATE: AclrByte NUMERIC "0" +// Retrieval info: PRIVATE: AclrOutput NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: Clken NUMERIC "0" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "./rom_data/rom_data.mif" +// Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "1024" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: RegAddr NUMERIC "1" +// Retrieval info: PRIVATE: RegOutput NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: SingleClock NUMERIC "1" +// Retrieval info: PRIVATE: UseDQRAM NUMERIC "0" +// Retrieval info: PRIVATE: WidthAddr NUMERIC "10" +// Retrieval info: PRIVATE: WidthData NUMERIC "10" +// Retrieval info: PRIVATE: rden NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: INIT_FILE STRING "./rom_data/rom_data.mif" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V" +// Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "1024" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM" +// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "10" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "10" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: address 0 0 10 0 INPUT NODEFVAL "address[9..0]" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: q 0 0 10 0 OUTPUT NODEFVAL "q[9..0]" +// Retrieval info: CONNECT: @address_a 0 0 10 0 address 0 0 10 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 10 0 @q_a 0 0 10 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL ROM.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL ROM.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL ROM.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL ROM.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL ROM_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL ROM_bb.v TRUE +// Retrieval info: LIB_FILE: altera_mf diff --git a/part_3/mylib/counter_10.v b/part_3/mylib/counter_10.v new file mode 100755 index 0000000..72c96fa --- /dev/null +++ b/part_3/mylib/counter_10.v @@ -0,0 +1,18 @@ +`timescale 1ns / 100ps + +module counter_10(clock,enable,count); + + parameter BIT_SZ = 10; + input clock; + input enable; + output [BIT_SZ-1:0] count; + + reg [BIT_SZ-1:0] count; + + initial count = 0; + + always @ (posedge clock) + if(enable == 1'b1) + count <= count + 1'b1; + +endmodule \ No newline at end of file diff --git a/part_3/mylib/hex_to_7seg.v b/part_3/mylib/hex_to_7seg.v new file mode 100755 index 0000000..82aa9a5 --- /dev/null +++ b/part_3/mylib/hex_to_7seg.v @@ -0,0 +1,27 @@ +module hex_to_7seg (out, in); + + output [6:0] out; + input [3:0] in; + + reg [6:0] out; + + always @ (*) + case(in) + 4'h0: out = 7'b1000000; + 4'h1: out = 7'b1111001; + 4'h2: out = 7'b0100100; + 4'h3: out = 7'b0110000; + 4'h4: out = 7'b0011001; + 4'h5: out = 7'b0010010; + 4'h6: out = 7'b0000010; + 4'h7: out = 7'b1111000; + 4'h8: out = 7'b0000000; + 4'h9: out = 7'b0011000; + 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_3/mylib/pwm.v b/part_3/mylib/pwm.v new file mode 100755 index 0000000..6a6e10c --- /dev/null +++ b/part_3/mylib/pwm.v @@ -0,0 +1,25 @@ +module pwm(clk, data_in, load, pwm_out); + + input clk; + input [9:0] data_in; + input load; + output pwm_out; + + reg[9:0] d; + reg [9:0] count; + 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 \ No newline at end of file diff --git a/part_3/mylib/spi2adc.v b/part_3/mylib/spi2adc.v new file mode 100755 index 0000000..3878f71 --- /dev/null +++ b/part_3/mylib/spi2adc.v @@ -0,0 +1,150 @@ +//------------------------------ +// Module name: spi2adc +// Function: SPI interface for MCP3002 ADC +// Creator: Peter Cheung +// Version: 1.1 +// Date: 24 Jan 2014 +//------------------------------ + +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 + 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 + end + + always @ (posedge sysclk) // + if (ctr==0) begin + ctr <= TIME_CONSTANT; + clk_1MHz <= ~clk_1MHz; // toggle the output clock for squarewave + end + else + ctr <= ctr - 1'b1; +// ---- 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 clk_1MHz) 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 clk_1MHz) + if((adc_cs==1'b0)&&(shift_ena==1'b1)) // start shifting data_in + shift_reg <= {shift_reg[8:0],sdata_from_adc}; + + // Latch converted output data + always @(posedge clk_1MHz) + 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_3/mylib/spi2dac.v b/part_3/mylib/spi2dac.v new file mode 100755 index 0000000..586a231 --- /dev/null +++ b/part_3/mylib/spi2dac.v @@ -0,0 +1,128 @@ +//------------------------------ +// Module name: spi2dac +// Function: SPI interface for MPC4911 DAC +// Creator: Peter Cheung +// Version: 2.0 +// Date: 8 Nov 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 + + 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 + end + + always @ (posedge sysclk) + if (ctr==0) begin + ctr <= TC; + clk_1MHz <= ~clk_1MHz; // toggle the output clock for squarewave + end + else + ctr <= ctr - 1'b1; + // ---- 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 clk_1MHz) // FSM state transition + 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 clk_1MHz) + if((dac_start==1'b1)&&(dac_cs==1'b1)) // parallel load data to shift reg + shift_reg <= {cmd,data_in,2'b00}; + else // .. 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 diff --git a/part_3/mylib/tick_5000.v b/part_3/mylib/tick_5000.v new file mode 100755 index 0000000..a048386 --- /dev/null +++ b/part_3/mylib/tick_5000.v @@ -0,0 +1,32 @@ +module tick_5000(CLOCK_IN, CLK_OUT); + + parameter NBIT = 16; + + input CLOCK_IN; + output CLK_OUT; + + reg [NBIT-1:0] count; + + reg CLK_OUT; + + initial + begin + count = 16'd4999; + CLK_OUT = 1'b0; + end + + always @ (posedge CLOCK_IN) + begin + if(count == 16'b0) + begin + CLK_OUT <= 1'b1; + count <= 16'd4999; + end + else + begin + count <= count - 1'b1; + CLK_OUT <= 1'b0; + end + end + +endmodule \ No newline at end of file -- cgit