Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
Whitney Knitter
Published © GPL3+

Simple FSK Baseband Transmitter on Eclypse Z7 + AWG Zmod

This project is a demo of a very simplified 2FSK baseband transmitter implemented on the Eclypse Z7 with AWG Zmod.

IntermediateFull instructions provided2 hours902
Simple FSK Baseband Transmitter on Eclypse Z7 + AWG Zmod

Things used in this project

Hardware components

Digilent Eclypse Z7: Zynq-7000 SoC Development Board with SYZYGY-compatible Expansion
×1
Digilent Zmod AWG 1411: 2-channel 14-bit Arbitrary Waveform Generator (AWG) Module
×1
Analog Discovery Pro ADP5250: All-In-One 1GS/s 100MHz Mixed Signal Oscilloscope, Function Generator, Power Supply, and DMM
Digilent Analog Discovery Pro ADP5250: All-In-One 1GS/s 100MHz Mixed Signal Oscilloscope, Function Generator, Power Supply, and DMM
×1

Software apps and online services

Vivado Design Suite
AMD Vivado Design Suite
Vitis Unified Software Platform
AMD Vitis Unified Software Platform
WaveForms
Digilent WaveForms

Story

Read more

Code

main.c

C/C++
#include <math.h>
#include <stdio.h>
#include "sleep.h"
#include "xtime_l.h"
#include "xaxidma.h"
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "mm2s_controller.h"

XAxiDma AxiDma;


int main()
{
    init_platform();

    XAxiDma_Config *CfgPtr; //DMA configuration pointer
	int Status, Index;
	u8 *TxBufferPtr;

	print("Hello World!\n\r");

	TxBufferPtr = (u8 *)TX_BUFFER_BASE;

	// Initialize memory to all zeros
	for(Index = 0; Index < MAX_PKT_LEN; Index ++){
		TxBufferPtr[Index] = 0x00;
	}

	// Initialize the XAxiDma device
	CfgPtr = XAxiDma_LookupConfig(DMA_DEV_ID);
	if (!CfgPtr) {
		xil_printf("No config found for %d\r\n", DMA_DEV_ID);
		return XST_FAILURE;
	}

	Status = XAxiDma_CfgInitialize(&AxiDma, CfgPtr);
	if (Status != XST_SUCCESS) {
		xil_printf("Initialization failed %d\r\n", Status);
		return XST_FAILURE;
	}

	XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE);

	TxBufferPtr[0] = 0xef;
	TxBufferPtr[1] = 0xbe;
	TxBufferPtr[2] = 0xad;
	TxBufferPtr[3] = 0xde;

	Xil_DCacheFlushRange((UINTPTR)TxBufferPtr, MAX_PKT_LEN);
	XAxiDma_Reset(&AxiDma);

	Status = XAxiDma_MM2Stransfer(&AxiDma,(UINTPTR) TxBufferPtr, MAX_PKT_LEN);
	if (Status != XST_SUCCESS){
		xil_printf("XAXIDMA_DMA_TO_DEVICE transfer failed...\r\n");
		return XST_FAILURE;
	}


    cleanup_platform();
    return 0;
}

mm2s_controller.c

C/C++
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "xgpio.h"
#include "xaxidma.h"
#include "xstatus.h"
#include "xil_printf.h"
#include "xil_assert.h"
#include "xparameters.h"
#include "mm2s_controller.h"

u32 XAxiDma_MM2Stransfer(XAxiDma *InstancePtr, UINTPTR BuffAddr, u32 Length){

	u32 WordBits;

	// Check scatter gather is not enabled
	if (XAxiDma_HasSg(InstancePtr)){
		xil_printf("Scatter gather is not supported\r\n");
		return XST_FAILURE;
	}

	// Check that the AXI DMA controller has the MM2S port (read channel) enabled in the HW design
	if (!InstancePtr->HasMm2S) {
		xil_printf("MM2S channel is not enabled.\r\n");
		return XST_FAILURE;
	}

	// Check that the requested transfer length is at least 1, but not
	// greater than the max length the DMA's configuration can transfer
	if ((Length < 1) || (Length > InstancePtr->TxBdRing.MaxTransferLen)){
		xil_printf("Invalid MM2S transfer length: %d\r\n", Length);
		return XST_FAILURE;
	}

	// If the engine is doing transfer, cannot submit
	if (!(XAxiDma_ReadReg(InstancePtr->TxBdRing.ChanBase, XAXIDMA_SR_OFFSET) & XAXIDMA_HALTED_MASK)){
		if (XAxiDma_Busy(InstancePtr,XAXIDMA_DMA_TO_DEVICE)){
			xil_printf("MM2S engine is busy\r\n");
			return XST_FAILURE;
		}
	}

	if (!InstancePtr->MicroDmaMode){
		WordBits = (u32)((InstancePtr->TxBdRing.DataWidth) - 1);
	} else {
		WordBits = XAXIDMA_MICROMODE_MIN_BUF_ALIGN;
	}

	if ((BuffAddr & WordBits)){
		if (!InstancePtr->TxBdRing.HasDRE){
			xil_printf("Unaligned transfer without DRE %x\r\n",(unsigned int)BuffAddr);
			return XST_FAILURE;
		}
	}

	// set the run bit
	XAxiDma_WriteReg(InstancePtr->TxBdRing.ChanBase,
			         XAXIDMA_CR_OFFSET,
					 XAxiDma_ReadReg(InstancePtr->TxBdRing.ChanBase,XAXIDMA_CR_OFFSET)| XAXIDMA_CR_RUNSTOP_MASK);

	XAxiDma_WriteReg(InstancePtr->TxBdRing.ChanBase, XAXIDMA_SRCADDR_OFFSET, LOWER_32_BITS(BuffAddr));

	if (InstancePtr->AddrWidth > 32){
		XAxiDma_WriteReg(InstancePtr->TxBdRing.ChanBase, XAXIDMA_SRCADDR_MSB_OFFSET, UPPER_32_BITS(BuffAddr));
	}

	// Writing length in bytes to the buffer transfer length register starts the transfer
	XAxiDma_WriteReg(InstancePtr->TxBdRing.ChanBase, XAXIDMA_BUFFLEN_OFFSET, Length);

	return XST_SUCCESS;
}

mm2s_controller.h

C/C++
#ifndef SRC_MM2S_CONTROLLER_H_
#define SRC_MM2S_CONTROLLER_H_

#define DMA_DEV_ID		    XPAR_AXIDMA_0_DEVICE_ID
#define DMA_BASEADDR        XPAR_AXIDMA_0_BASEADDR
#define DDR_BASE_ADDR		XPAR_PS7_DDR_0_S_AXI_BASEADDR
#define MEM_BASE_ADDR		(DDR_BASE_ADDR + 0x1000000)
#define TX_BUFFER_BASE		(MEM_BASE_ADDR + 0x00100000)
#define RX_BUFFER_BASE		(MEM_BASE_ADDR + 0x00300000)
#define RX_BUFFER_HIGH		(MEM_BASE_ADDR + 0x004FFFFF)
#define V_BUFFER_BASE       (MEM_BASE_ADDR + 0x00500000)

// 0x400/1024 bytes=256 DMA cycles
// 0x80/128 bytes=32 DMA cycles
// 0x20/32 bytes=8 DMA cycles
// 0x08/8 bytes=2 DMA cycles
// 0x04/4 bytes=1 DMA cycles

#define MAX_PKT_LEN		    0x04
#define MIN_PKT_LEN		    0x01
#define NUM_TRANSFERS	    1

u32 XAxiDma_MM2Stransfer(XAxiDma *InstancePtr, UINTPTR BuffAddr, u32 Length);

#endif /* SRC_MM2S_CONTROLLER_H_ */

sin_axis.v

Verilog
`timescale 1ns / 1ps

module sin_axis(
    input clk,
    input reset,
    input [31:0] s_axis_tdata,
    input [3:0] s_axis_tkeep,
    input s_axis_tlast,
    output reg s_axis_tready,
    input s_axis_tvalid,
    output reg [31:0] m_axis_tdata,
    output reg [3:0] m_axis_tkeep,
    output reg m_axis_tlast,
    input m_axis_tready,
    output reg m_axis_tvalid, 
    output [2:0] state_reg
    );
    
    sin_sm sin_sm_i(
        .clk(clk),
        .rst(reset),
        .tdata_slave(tdata_slave),
        .tdata_master(tdata_master),
        .tx_pkt_done(tx_pkt_done)
    );
    
    
    reg tlast;
    reg [2:0] state_reg;
    
    wire tx_pkt_done;
    wire [31:0] tdata_master;
    reg [31:0] tdata_slave;
    
    
    parameter init               = 3'd0;
    parameter SetSlaveTready     = 3'd1;
    parameter CheckSlaveTvalid   = 3'd2;
    parameter ProcessTdata       = 3'd3;
    parameter CheckTlast         = 3'd4;
    
    always @ (posedge clk)
        begin
			// Default outputs            
			m_axis_tvalid <= 1'b0;
            
            if (reset == 1'b0)
                begin
                    tlast <= 1'b0;
                    tdata_slave[31:0] <= 32'd0;
                    s_axis_tready <= 1'b0;
                    m_axis_tdata[31:0] <= 32'd0;
                    m_axis_tkeep <= 4'h0;
                    m_axis_tlast <= 1'b0;
                    state_reg <= init;
                end
            else
                begin
                
                    case(state_reg) 
                        init : // 0 
                            begin
                                tlast <= 1'b0;
                                tdata_slave[31:0] <= 32'd0;
                                s_axis_tready <= 1'b0;
                                m_axis_tdata[31:0] <= 32'd0;
                                m_axis_tkeep <= 4'h0;
                                m_axis_tlast <= 1'b0;
                                state_reg <= SetSlaveTready;
                            end 
                            
                        SetSlaveTready : // 1
                            begin
                                s_axis_tready <= 1'b1;
                                state_reg <= CheckSlaveTvalid;
                            end 
                            
                        CheckSlaveTvalid : // 2
                            begin
                                if (s_axis_tkeep == 4'hf && s_axis_tvalid == 1'b1)
                                    begin
                                        s_axis_tready <= 1'b0;
                                        tlast <= s_axis_tlast;
                                        tdata_slave[31:0] <= s_axis_tdata[31:0];
                                        state_reg <= ProcessTdata;
                                    end
                                else
                                    begin 
                                        tdata_slave[31:0] <= 32'd0;
                                        state_reg <= CheckSlaveTvalid;
                                    end 
                            end
                            
                        ProcessTdata : // 3
                            begin 
                                m_axis_tkeep <= 4'hf;
                                m_axis_tlast <= tlast;
                                m_axis_tvalid <= 1'b1;
                                m_axis_tdata[31:0] <= tdata_master[31:0];
                                
                                if (m_axis_tready == 1'b1 && tx_pkt_done == 1'b1)
                                    begin 
                                        state_reg <= CheckTlast;
                                    end 
                                else
                                    begin 
                                        state_reg <= ProcessTdata;
                                    end 
                            end
                            
                        CheckTlast : // 4
                            begin 
                                if (m_axis_tlast == 1'b1)
                                    begin				
                                        state_reg <= init;
                                    end
                                else if (m_axis_tready == 1'b1)
                                    begin
                                        state_reg <= SetSlaveTready;
                                    end
                                else 
                                    begin 
                                        state_reg <= CheckTlast;
                                    end 
                            end 
                            
                    endcase 
                end
        end
endmodule

sin_lut.v

Verilog
`timescale 1ns / 1ps

module sin_lut(
    input clk,
    input rst,
    input [8:0] sel,
    output [15:0] DAC_code
    );
    
    reg [15:0] DAC_code;
    
    always @ (posedge clk)
        begin
            if (rst == 1'b0)
                begin 
                end
            else 
                begin
                    case (sel)
                        9'd0   : DAC_code = 16'h0000;
                        9'd1   : DAC_code = 16'h01C8;
                        9'd2   : DAC_code = 16'h0390;
                        9'd3   : DAC_code = 16'h0558;
                        9'd4   : DAC_code = 16'h0724;
                        9'd5   : DAC_code = 16'h08EC;
                        9'd6   : DAC_code = 16'h0AB0;
                        9'd7   : DAC_code = 16'h0C78;
                        9'd8   : DAC_code = 16'h0E3C;
                        9'd9   : DAC_code = 16'h1004;
                        9'd10  : DAC_code = 16'h11C4;
                        9'd11  : DAC_code = 16'h1388;
                        9'd12  : DAC_code = 16'h1548;
                        9'd13  : DAC_code = 16'h1708;
                        9'd14  : DAC_code = 16'h18C4;
                        9'd15  : DAC_code = 16'h1A7C;
                        9'd16  : DAC_code = 16'h1C38;
                        9'd17  : DAC_code = 16'h1DEC;
                        9'd18  : DAC_code = 16'h1FA0;
                        9'd19  : DAC_code = 16'h2154;
                        9'd20  : DAC_code = 16'h2304;
                        9'd21  : DAC_code = 16'h24B0;
                        9'd22  : DAC_code = 16'h2658;
                        9'd23  : DAC_code = 16'h2800;
                        9'd24  : DAC_code = 16'h29A4;
                        9'd25  : DAC_code = 16'h2B44;
                        9'd26  : DAC_code = 16'h2CE0;
                        9'd27  : DAC_code = 16'h2E78;
                        9'd28  : DAC_code = 16'h3010;
                        9'd29  : DAC_code = 16'h31A0;
                        9'd30  : DAC_code = 16'h3330;
                        9'd31  : DAC_code = 16'h34B8;
                        9'd32  : DAC_code = 16'h3640;
                        9'd33  : DAC_code = 16'h37C0;
                        9'd34  : DAC_code = 16'h3940;
                        9'd35  : DAC_code = 16'h3AB8;
                        9'd36  : DAC_code = 16'h3C2C;
                        9'd37  : DAC_code = 16'h3D9C;
                        9'd38  : DAC_code = 16'h3F08;
                        9'd39  : DAC_code = 16'h406C;
                        9'd40  : DAC_code = 16'h41D0;
                        9'd41  : DAC_code = 16'h432C;
                        9'd42  : DAC_code = 16'h4480;
                        9'd43  : DAC_code = 16'h45D0;
                        9'd44  : DAC_code = 16'h471C;
                        9'd45  : DAC_code = 16'h4864;
                        9'd46  : DAC_code = 16'h49A4;
                        9'd47  : DAC_code = 16'h4AE0;
                        9'd48  : DAC_code = 16'h4C14;
                        9'd49  : DAC_code = 16'h4D44;
                        9'd50  : DAC_code = 16'h4E6C;
                        9'd51  : DAC_code = 16'h4F90;
                        9'd52  : DAC_code = 16'h50AC;
                        9'd53  : DAC_code = 16'h51C4;
                        9'd54  : DAC_code = 16'h52D4;
                        9'd55  : DAC_code = 16'h53DC;
                        9'd56  : DAC_code = 16'h54E0;
                        9'd57  : DAC_code = 16'h55DC;
                        9'd58  : DAC_code = 16'h56D4;
                        9'd59  : DAC_code = 16'h57C0;
                        9'd60  : DAC_code = 16'h58A8;
                        9'd61  : DAC_code = 16'h598C;
                        9'd62  : DAC_code = 16'h5A64;
                        9'd63  : DAC_code = 16'h5B38;
                        9'd64  : DAC_code = 16'h5C04;
                        9'd65  : DAC_code = 16'h5CC8;
                        9'd66  : DAC_code = 16'h5D88;
                        9'd67  : DAC_code = 16'h5E3C;
                        9'd68  : DAC_code = 16'h5EEC;
                        9'd69  : DAC_code = 16'h5F94;
                        9'd70  : DAC_code = 16'h6034;
                        9'd71  : DAC_code = 16'h60CC;
                        9'd72  : DAC_code = 16'h6160;
                        9'd73  : DAC_code = 16'h61E8;
                        9'd74  : DAC_code = 16'h6268;
                        9'd75  : DAC_code = 16'h62E4;
                        9'd76  : DAC_code = 16'h6358;
                        9'd77  : DAC_code = 16'h63C0;
                        9'd78  : DAC_code = 16'h6424;
                        9'd79  : DAC_code = 16'h6480;
                        9'd80  : DAC_code = 16'h64D4;
                        9'd81  : DAC_code = 16'h6520;
                        9'd82  : DAC_code = 16'h6564;
                        9'd83  : DAC_code = 16'h659C;
                        9'd84  : DAC_code = 16'h65D0;
                        9'd85  : DAC_code = 16'h65FC;
                        9'd86  : DAC_code = 16'h6620;
                        9'd87  : DAC_code = 16'h663C;
                        9'd88  : DAC_code = 16'h6650;
                        9'd89  : DAC_code = 16'h665C;
                        9'd90  : DAC_code = 16'h6660;
                        9'd91  : DAC_code = 16'h665C;
                        9'd92  : DAC_code = 16'h6650;
                        9'd93  : DAC_code = 16'h663C;
                        9'd94  : DAC_code = 16'h6620;
                        9'd95  : DAC_code = 16'h65FC;
                        9'd96  : DAC_code = 16'h65D0;
                        9'd97  : DAC_code = 16'h659C;
                        9'd98  : DAC_code = 16'h6564;
                        9'd99  : DAC_code = 16'h6520;
                        9'd100 : DAC_code = 16'h64D4;
                        9'd101 : DAC_code = 16'h6480;
                        9'd102 : DAC_code = 16'h6424;
                        9'd103 : DAC_code = 16'h63C0;
                        9'd104 : DAC_code = 16'h6358;
                        9'd105 : DAC_code = 16'h62E4;
                        9'd106 : DAC_code = 16'h6268;
                        9'd107 : DAC_code = 16'h61E8;
                        9'd108 : DAC_code = 16'h6160;
                        9'd109 : DAC_code = 16'h60CC;
                        9'd110 : DAC_code = 16'h6034;
                        9'd111 : DAC_code = 16'h5F94;
                        9'd112 : DAC_code = 16'h5EEC;
                        9'd113 : DAC_code = 16'h5E3C;
                        9'd114 : DAC_code = 16'h5D88;
                        9'd115 : DAC_code = 16'h5CC8;
                        9'd116 : DAC_code = 16'h5C04;
                        9'd117 : DAC_code = 16'h5B38;
                        9'd118 : DAC_code = 16'h5A64;
                        9'd119 : DAC_code = 16'h598C;
                        9'd120 : DAC_code = 16'h58A8;
                        9'd121 : DAC_code = 16'h57C0;
                        9'd122 : DAC_code = 16'h56D4;
                        9'd123 : DAC_code = 16'h55DC;
                        9'd124 : DAC_code = 16'h54E0;
                        9'd125 : DAC_code = 16'h53DC;
                        9'd126 : DAC_code = 16'h52D4;
                        9'd127 : DAC_code = 16'h51C4;
                        9'd128 : DAC_code = 16'h50AC;
                        9'd129 : DAC_code = 16'h4F90;
                        9'd130 : DAC_code = 16'h4E6C;
                        9'd131 : DAC_code = 16'h4D44;
                        9'd132 : DAC_code = 16'h4C14;
                        9'd133 : DAC_code = 16'h4AE0;
                        9'd134 : DAC_code = 16'h49A4;
                        9'd135 : DAC_code = 16'h4864;
                        9'd136 : DAC_code = 16'h471C;
                        9'd137 : DAC_code = 16'h45D0;
                        9'd138 : DAC_code = 16'h4480;
                        9'd139 : DAC_code = 16'h432C;
                        9'd140 : DAC_code = 16'h41D0;
                        9'd141 : DAC_code = 16'h406C;
                        9'd142 : DAC_code = 16'h3F08;
                        9'd143 : DAC_code = 16'h3D9C;
                        9'd144 : DAC_code = 16'h3C2C;
                        9'd145 : DAC_code = 16'h3AB8;
                        9'd146 : DAC_code = 16'h3940;
                        9'd147 : DAC_code = 16'h37C0;
                        9'd148 : DAC_code = 16'h3640;
                        9'd149 : DAC_code = 16'h34B8;
                        9'd150 : DAC_code = 16'h3330;
                        9'd151 : DAC_code = 16'h31A0;
                        9'd152 : DAC_code = 16'h3010;
                        9'd153 : DAC_code = 16'h2E78;
                        9'd154 : DAC_code = 16'h2CE0;
                        9'd155 : DAC_code = 16'h2B44;
                        9'd156 : DAC_code = 16'h29A4;
                        9'd157 : DAC_code = 16'h2800;
                        9'd158 : DAC_code = 16'h2658;
                        9'd159 : DAC_code = 16'h24B0;
                        9'd160 : DAC_code = 16'h2304;
                        9'd161 : DAC_code = 16'h2154;
                        9'd162 : DAC_code = 16'h1FA0;
                        9'd163 : DAC_code = 16'h1DEC;
                        9'd164 : DAC_code = 16'h1C38;
                        9'd165 : DAC_code = 16'h1A7C;
                        9'd166 : DAC_code = 16'h18C4;
                        9'd167 : DAC_code = 16'h1708;
                        9'd168 : DAC_code = 16'h1548;
                        9'd169 : DAC_code = 16'h1388;
                        9'd170 : DAC_code = 16'h11C4;
                        9'd171 : DAC_code = 16'h1004;
                        9'd172 : DAC_code = 16'h0E3C;
                        9'd173 : DAC_code = 16'h0C78;
                        9'd174 : DAC_code = 16'h0AB0;
                        9'd175 : DAC_code = 16'h08EC;
                        9'd176 : DAC_code = 16'h0724;
                        9'd177 : DAC_code = 16'h0558;
                        9'd178 : DAC_code = 16'h0390;
                        9'd179 : DAC_code = 16'h01C8;
                        9'd180 : DAC_code = 16'h0000;
                        9'd181 : DAC_code = 16'hFE37;
                        9'd182 : DAC_code = 16'hFC6F;
                        9'd183 : DAC_code = 16'hFAA7;
                        9'd184 : DAC_code = 16'hF8DB;
                        9'd185 : DAC_code = 16'hF713;
                        9'd186 : DAC_code = 16'hF54F;
                        9'd187 : DAC_code = 16'hF387;
                        9'd188 : DAC_code = 16'hF1C3;
                        9'd189 : DAC_code = 16'hEFFB;
                        9'd190 : DAC_code = 16'hEE3B;
                        9'd191 : DAC_code = 16'hEC77;
                        9'd192 : DAC_code = 16'hEAB7;
                        9'd193 : DAC_code = 16'hE8F7;
                        9'd194 : DAC_code = 16'hE73B;
                        9'd195 : DAC_code = 16'hE583;
                        9'd196 : DAC_code = 16'hE3C7;
                        9'd197 : DAC_code = 16'hE213;
                        9'd198 : DAC_code = 16'hE05F;
                        9'd199 : DAC_code = 16'hDEAB;
                        9'd200 : DAC_code = 16'hDCFB;
                        9'd201 : DAC_code = 16'hDB4F;
                        9'd202 : DAC_code = 16'hD9A7;
                        9'd203 : DAC_code = 16'hD7FF;
                        9'd204 : DAC_code = 16'hD65B;
                        9'd205 : DAC_code = 16'hD4BB;
                        9'd206 : DAC_code = 16'hD31F;
                        9'd207 : DAC_code = 16'hD187;
                        9'd208 : DAC_code = 16'hCFEF;
                        9'd209 : DAC_code = 16'hCE5F;
                        9'd210 : DAC_code = 16'hCCCF;
                        9'd211 : DAC_code = 16'hCB47;
                        9'd212 : DAC_code = 16'hC9BF;
                        9'd213 : DAC_code = 16'hC83F;
                        9'd214 : DAC_code = 16'hC6BF;
                        9'd215 : DAC_code = 16'hC547;
                        9'd216 : DAC_code = 16'hC3D3;
                        9'd217 : DAC_code = 16'hC263;
                        9'd218 : DAC_code = 16'hC0F7;
                        9'd219 : DAC_code = 16'hBF93;
                        9'd220 : DAC_code = 16'hBE2F;
                        9'd221 : DAC_code = 16'hBCD3;
                        9'd222 : DAC_code = 16'hBB7F;
                        9'd223 : DAC_code = 16'hBA2F;
                        9'd224 : DAC_code = 16'hB8E3;
                        9'd225 : DAC_code = 16'hB79B;
                        9'd226 : DAC_code = 16'hB65B;
                        9'd227 : DAC_code = 16'hB51F;
                        9'd228 : DAC_code = 16'hB3EB;
                        9'd229 : DAC_code = 16'hB2BB;
                        9'd230 : DAC_code = 16'hB193;
                        9'd231 : DAC_code = 16'hB06F;
                        9'd232 : DAC_code = 16'hAF53;
                        9'd233 : DAC_code = 16'hAE3B;
                        9'd234 : DAC_code = 16'hAD2B;
                        9'd235 : DAC_code = 16'hAC23;
                        9'd236 : DAC_code = 16'hAB1F;
                        9'd237 : DAC_code = 16'hAA23;
                        9'd238 : DAC_code = 16'hA92B;
                        9'd239 : DAC_code = 16'hA83F;
                        9'd240 : DAC_code = 16'hA757;
                        9'd241 : DAC_code = 16'hA673;
                        9'd242 : DAC_code = 16'hA59B;
                        9'd243 : DAC_code = 16'hA4C7;
                        9'd244 : DAC_code = 16'hA3FB;
                        9'd245 : DAC_code = 16'hA337;
                        9'd246 : DAC_code = 16'hA277;
                        9'd247 : DAC_code = 16'hA1C3;
                        9'd248 : DAC_code = 16'hA113;
                        9'd249 : DAC_code = 16'hA06B;
                        9'd250 : DAC_code = 16'h9FCB;
                        9'd251 : DAC_code = 16'h9F33;
                        9'd252 : DAC_code = 16'h9E9F;
                        9'd253 : DAC_code = 16'h9E17;
                        9'd254 : DAC_code = 16'h9D97;
                        9'd255 : DAC_code = 16'h9D1B;
                        9'd256 : DAC_code = 16'h9CA7;
                        9'd257 : DAC_code = 16'h9C3F;
                        9'd258 : DAC_code = 16'h9BDB;
                        9'd259 : DAC_code = 16'h9B7F;
                        9'd260 : DAC_code = 16'h9B2B;
                        9'd261 : DAC_code = 16'h9ADF;
                        9'd262 : DAC_code = 16'h9A9B;
                        9'd263 : DAC_code = 16'h9A63;
                        9'd264 : DAC_code = 16'h9A2F;
                        9'd265 : DAC_code = 16'h9A03;
                        9'd266 : DAC_code = 16'h99DF;
                        9'd267 : DAC_code = 16'h99C3;
                        9'd268 : DAC_code = 16'h99AF;
                        9'd269 : DAC_code = 16'h99A3;
                        9'd270 : DAC_code = 16'h999F;
                        9'd271 : DAC_code = 16'h99A3;
                        9'd272 : DAC_code = 16'h99AF;
                        9'd273 : DAC_code = 16'h99C3;
                        9'd274 : DAC_code = 16'h99DF;
                        9'd275 : DAC_code = 16'h9A03;
                        9'd276 : DAC_code = 16'h9A2F;
                        9'd277 : DAC_code = 16'h9A63;
                        9'd278 : DAC_code = 16'h9A9B;
                        9'd279 : DAC_code = 16'h9ADF;
                        9'd280 : DAC_code = 16'h9B2B;
                        9'd281 : DAC_code = 16'h9B7F;
                        9'd282 : DAC_code = 16'h9BDB;
                        9'd283 : DAC_code = 16'h9C3F;
                        9'd284 : DAC_code = 16'h9CA7;
                        9'd285 : DAC_code = 16'h9D1B;
                        9'd286 : DAC_code = 16'h9D97;
                        9'd287 : DAC_code = 16'h9E17;
                        9'd288 : DAC_code = 16'h9E9F;
                        9'd289 : DAC_code = 16'h9F33;
                        9'd290 : DAC_code = 16'h9FCB;
                        9'd291 : DAC_code = 16'hA06B;
                        9'd292 : DAC_code = 16'hA113;
                        9'd293 : DAC_code = 16'hA1C3;
                        9'd294 : DAC_code = 16'hA277;
                        9'd295 : DAC_code = 16'hA337;
                        9'd296 : DAC_code = 16'hA3FB;
                        9'd297 : DAC_code = 16'hA4C7;
                        9'd298 : DAC_code = 16'hA59B;
                        9'd299 : DAC_code = 16'hA673;
                        9'd300 : DAC_code = 16'hA757;
                        9'd301 : DAC_code = 16'hA83F;
                        9'd302 : DAC_code = 16'hA92B;
                        9'd303 : DAC_code = 16'hAA23;
                        9'd304 : DAC_code = 16'hAB1F;
                        9'd305 : DAC_code = 16'hAC23;
                        9'd306 : DAC_code = 16'hAD2B;
                        9'd307 : DAC_code = 16'hAE3B;
                        9'd308 : DAC_code = 16'hAF53;
                        9'd309 : DAC_code = 16'hB06F;
                        9'd310 : DAC_code = 16'hB193;
                        9'd311 : DAC_code = 16'hB2BB;
                        9'd312 : DAC_code = 16'hB3EB;
                        9'd313 : DAC_code = 16'hB51F;
                        9'd314 : DAC_code = 16'hB65B;
                        9'd315 : DAC_code = 16'hB79B;
                        9'd316 : DAC_code = 16'hB8E3;
                        9'd317 : DAC_code = 16'hBA2F;
                        9'd318 : DAC_code = 16'hBB7F;
                        9'd319 : DAC_code = 16'hBCD3;
                        9'd320 : DAC_code = 16'hBE2F;
                        9'd321 : DAC_code = 16'hBF93;
                        9'd322 : DAC_code = 16'hC0F7;
                        9'd323 : DAC_code = 16'hC263;
                        9'd324 : DAC_code = 16'hC3D3;
                        9'd325 : DAC_code = 16'hC547;
                        9'd326 : DAC_code = 16'hC6BF;
                        9'd327 : DAC_code = 16'hC83F;
                        9'd328 : DAC_code = 16'hC9BF;
                        9'd329 : DAC_code = 16'hCB47;
                        9'd330 : DAC_code = 16'hCCCF;
                        9'd331 : DAC_code = 16'hCE5F;
                        9'd332 : DAC_code = 16'hCFEF;
                        9'd333 : DAC_code = 16'hD187;
                        9'd334 : DAC_code = 16'hD31F;
                        9'd335 : DAC_code = 16'hD4BB;
                        9'd336 : DAC_code = 16'hD65B;
                        9'd337 : DAC_code = 16'hD7FF;
                        9'd338 : DAC_code = 16'hD9A7;
                        9'd339 : DAC_code = 16'hDB4F;
                        9'd340 : DAC_code = 16'hDCFB;
                        9'd341 : DAC_code = 16'hDEAB;
                        9'd342 : DAC_code = 16'hE05F;
                        9'd343 : DAC_code = 16'hE213;
                        9'd344 : DAC_code = 16'hE3C7;
                        9'd345 : DAC_code = 16'hE583;
                        9'd346 : DAC_code = 16'hE73B;
                        9'd347 : DAC_code = 16'hE8F7;
                        9'd348 : DAC_code = 16'hEAB7;
                        9'd349 : DAC_code = 16'hEC77;
                        9'd350 : DAC_code = 16'hEE3B;
                        9'd351 : DAC_code = 16'hEFFB;
                        9'd352 : DAC_code = 16'hF1C3;
                        9'd353 : DAC_code = 16'hF387;
                        9'd354 : DAC_code = 16'hF54F;
                        9'd355 : DAC_code = 16'hF713;
                        9'd356 : DAC_code = 16'hF8DB;
                        9'd357 : DAC_code = 16'hFAA7;
                        9'd358 : DAC_code = 16'hFC6F;
                        9'd359 : DAC_code = 16'hFE37;
                        9'd360 : DAC_code = 16'h0000;
                        default : DAC_code = 16'h0000;
                    endcase
                end
        end
    
endmodule

sin_sm.v

Verilog
`timescale 1ns / 1ps

module sin_sm(
    input clk,
    input rst,
    input [31:0] tdata_slave,
    output reg [31:0] tdata_master,
    output reg tx_pkt_done
    );
    
    parameter T0_period       = 3'd2;
    parameter T1_period       = 3'd1;
    parameter unit_circle_deg = 9'd360;
    
    reg [31:0] tdata;
    reg [2:0]  period;
    reg [2:0]  period_cntr;
    reg [8:0]  degree_cntr;
    reg [4:0]  tdata_sel_cntr;
    
    wire [15:0] DAC_code;
    
    sin_lut sin_lut_i(
        .clk(clk),
        .rst(rst),
        .sel(degree_cntr),
        .DAC_code(DAC_code)
    );
    
    always @ (posedge clk)
        begin
            if (rst == 1'b0)
                begin
                    tdata_master[31:0] <= 32'd0;
                end
            else
                begin
                    tdata_master[31:16] <= DAC_code[15:0];
                    tdata_master[15:0]  <= DAC_code[15:0];
                end
        end 
        
    always @ (posedge clk)
        begin
            if (rst == 1'b0)
                begin
                    tdata[31:0] <= 32'd0;
                end
            else
                begin
                    tdata[31:0] <= tdata_slave[31:0];
                end
        end

    reg current_tx_bit;
    reg tx_pkt_done;
    always @ (tdata_sel_cntr)
        begin 
            case (tdata_sel_cntr) 
                32'd0   : 
                    begin
                        current_tx_bit <= tdata[0];
                        tx_pkt_done <= 1'b0;
                    end 
                32'd1   : 
                    begin
                         current_tx_bit <= tdata[1];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd2   : 
                    begin
                         current_tx_bit <= tdata[2];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd3   : 
                    begin
                         current_tx_bit <= tdata[3];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd4   : 
                    begin
                         current_tx_bit <= tdata[4];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd5   : 
                    begin
                         current_tx_bit <= tdata[5];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd6   : 
                    begin
                         current_tx_bit <= tdata[6];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd7   : 
                    begin
                         current_tx_bit <= tdata[7];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd8   : 
                    begin
                         current_tx_bit <= tdata[8];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd9   : 
                    begin
                         current_tx_bit <= tdata[9];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd10  : 
                    begin
                         current_tx_bit <= tdata[10];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd11  : 
                    begin
                         current_tx_bit <= tdata[11];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd12  : 
                    begin
                         current_tx_bit <= tdata[12];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd13  : 
                    begin
                         current_tx_bit <= tdata[13];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd14  : 
                    begin
                         current_tx_bit <= tdata[14];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd15  : 
                    begin
                         current_tx_bit <= tdata[15];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd16  : 
                    begin
                         current_tx_bit <= tdata[16];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd17  : 
                    begin
                         current_tx_bit <= tdata[17];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd18  : 
                    begin
                         current_tx_bit <= tdata[18];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd19  : 
                    begin
                         current_tx_bit <= tdata[19];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd20  : 
                    begin
                         current_tx_bit <= tdata[20];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd21  : 
                    begin
                         current_tx_bit <= tdata[21];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd22  : 
                    begin
                         current_tx_bit <= tdata[22];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd23  : 
                    begin
                         current_tx_bit <= tdata[23];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd24  : 
                    begin
                         current_tx_bit <= tdata[24];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd25  : 
                    begin
                         current_tx_bit <= tdata[25];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd26  : 
                    begin
                         current_tx_bit <= tdata[26];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd27  : 
                    begin
                         current_tx_bit <= tdata[27];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd28  : 
                    begin
                         current_tx_bit <= tdata[28];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd29  : 
                    begin
                         current_tx_bit <= tdata[29];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd30  : 
                    begin
                         current_tx_bit <= tdata[30];
                         tx_pkt_done <= 1'b0;
                    end 
                32'd31  : 
                    begin
                         current_tx_bit <= tdata[31];
                         tx_pkt_done <= 1'b1;
                    end 
                default : 
                    begin
                        current_tx_bit <= 1'b0;
                        tx_pkt_done <= 1'b0;
                    end
            endcase 
        end
        
    always @ (posedge clk)
        begin 
            if (current_tx_bit == 1'b1)
                period <= T1_period;
            else
                period <= T0_period;
        end
        
    reg incr_degree_cntr;
    reg degree_cntr_done;
    always @ (posedge clk)
        begin 
            if (rst == 1'b0)
                begin
                    degree_cntr <= 9'd0;
                    degree_cntr_done <= 1'b0; 
                end
            else if (incr_degree_cntr == 1'b1)
                begin
                    if (degree_cntr < unit_circle_deg)
                        begin
                            degree_cntr <= degree_cntr + 1;
                            degree_cntr_done <= 1'b0;
                        end
                    else
                        begin
                            degree_cntr <= 9'd0;
                            degree_cntr_done <= 1'b1;
                        end
                end
            else
                begin
                    degree_cntr <= degree_cntr;
                end
        end 
    
    always @ (posedge clk)
        begin 
            if (rst == 1'b0)
                begin
                    incr_degree_cntr = 1'b0;
                    period_cntr <= 3'd0;
                end
            else
                begin
                    if (period_cntr == period)
                        begin
                            incr_degree_cntr = 1'b1;
                            period_cntr <= 3'd0;
                        end
                    else
                        begin 
                            incr_degree_cntr = 1'b0;
                            period_cntr <= period_cntr + 1;
                        end 
                end
        end 
 
    always @ (posedge clk)
        begin 
            if (rst == 1'b0)
                begin
                    tdata_sel_cntr <= 5'd0;
                end 
            else 
                begin
                    if (degree_cntr_done == 1'b1)
                        begin
                            tdata_sel_cntr <= tdata_sel_cntr + 1;
                        end
                    else
                        begin
                            tdata_sel_cntr <= tdata_sel_cntr;
                        end
                end 
        end  
    
endmodule

Credits

Whitney Knitter
172 projects • 1805 followers
All thoughts/opinions are my own and do not reflect those of any company/entity I currently/previously associate with.
Contact

Comments

Please log in or sign up to comment.