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