codec.v
module codec (clock, sync, data_in, data_out);

// PARAMETERS

    // SMI INSTANCE NAME

    parameter INSTANCE = "";

// INTERFACE

    input  clock;
    input  sync;
    input  data_in;
    output data_out;

// CONSTANTS

    // WORD WIDTH IN BITS

    parameter WIDTH = 16;

    // MESSAGE TYPE IDENTIFIERS

    parameter DEV_WRITE = 0;
    parameter DEV_READ = 1;
    
// INTERNAL SIGNALS

    // WRITE AND READ CHANNEL DATA WORDS

    reg [WIDTH-1:0] dac_data;
    reg [WIDTH-1:0] adc_data;

    // OUTPUT

    reg data;

    // BIT COUNTER COUNTS FROM 15 DOWN TO 0, SET TO 16 WHEN INACTIVE

    integer count;

    // SMI MODEL IDENTIFIER

    integer id;

// IMPLEMENTATION

    initial
    begin
        // SET COUNTER INACTIVE

        count <= WIDTH;

        // REGISTER THE MODEL INSTANCE WITH SMI

        $smi_initial(id, "codec", INSTANCE);

        // PRINT THE CONFIGURATION

        $display("MODEL-%d: codec(%s)[WORD WIDTH=%d]", id, INSTANCE, WIDTH);
    end

    // WRAP AROUND COUNTER COUNTS DOWN FROM "WIDTH" TO 0

    always @(negedge clock)

        // IF sync THEN START COUNTER

        if (sync) count <= WIDTH-1;

        // ELSE IF COUNTER EXPIRED SET INACTIVE

        else if (count == 0) count <= WIDTH;

        // ELSE IF COUNTER ACTIVE COUNT DOWN

        else if (count != WIDTH) count <= count - 1;

    // SAMPLE INPUT BIT STREAM, ASSEMBLE WORDS AND SEND TO THE SOFTWARE MODEL

    always @(negedge clock)

        // IF THE COUNTER IS ACTIVE

        if (count != WIDTH)
        begin
            // FETCH THE WRITE CHANNEL BIT

            dac_data[count] = data_in;

            // IF THE WRITE CHANNEL WORD IS COMPLETE, SEND TO THE SOFTWARE MODEL

            if (count == 0) $smi_write(id, DEV_WRITE, dac_data);
        end

    // READ WORDS FROM THE SOFTWARE MODEL AND OUTPUT EACH BIT SERIALLY

    always @(posedge clock)

        // IF THE COUNTER IS ACTIVE

        if (count != WIDTH)
        begin

            // FETCH THE READ CHANNEL WORD IF THE COUNTER IS AT THE MSB

            if (count == WIDTH-1)
                $smi_read(id, DEV_READ, adc_data);

            // SET THE OUTPUT EQUAL TO A BIT IN THE READ CHANNEL WORD

            data <= adc_data[count];

        end

        // ELSE SET THE OUTPUT TO ZERO

        else data <= 0;

    // SET THE SERIAL OUTPUT

    assign data_out = data;

endmodule
© Copyright 2000-2001 Adrian Lewis