Skip to content
Snippets Groups Projects
Commit 88bb359f authored by jf3g19's avatar jf3g19
Browse files

initial commit

parents
Branches
No related tags found
No related merge requests found
DA.sv 0 → 100644
/*
======= Signed DA MAC =======
- This is a Signed MAC block based on a distributed arithmetic architechture
- The input is an [N*BW] unpacked array of packed array of arrays
- The LUT corresponding to coefficients with which each value is multiplied is specified in DA_LUT.sv
- This LUT must be specified for the number of input bits
- The output is of size 2N (+ 8 guard bits)
======= Signed DA MAC =======
*/
import DA_LUT::multiplication_coefficients;
import DA_LUT::clog2;
module DA_MAC #(parameter BW = DA_LUT::BW, parameter N = DA_LUT::N)
(input logic signed [BW-1:0] in [0:N-1],
input logic input_ready, ck, rst,
output logic signed [(2*N-1)+8:0] out,
output logic output_ready);
// ==== Local Variables ====
logic signed [N-1:0] shifted_out;
logic signed [(N-1)+8:0] partial_sum;
typedef enum logic [1:0] {waiting, loading, processing, saving} state_type;
state_type state, next_state;
logic load, reset_accumulator, compute, count;
logic [clog2(BW):0] address;
// ==== Local Variables ====
// ==== generate the multiplication addresses ====
logic unsigned [N-1:0] multiplication_addresses [0:BW-1];
always_ff@(posedge ck, posedge rst)
if(rst)
multiplication_addresses <= '{default:'0};
else if(load)
begin
for(int i=0; i < BW; i++)
begin
for(int j=0; j < N; j++)
begin
multiplication_addresses[i][j] <= in[j][i];
end
end
end
// ==== generate the multiplication addresses ====
// ==== DA accumulator ====
always_ff @(posedge ck, posedge rst)
if (reset_accumulator)
begin
partial_sum <= '0;
shifted_out <= '0;
end
else
begin
if(compute)
begin
if(address < N-1)
begin
shifted_out <= {partial_sum[0], shifted_out[N-1:1]};
partial_sum <= {partial_sum[(N-1)+8],partial_sum[(N-1)+8:1]} + multiplication_coefficients[multiplication_addresses[address]];
end
else
begin
shifted_out <= {partial_sum[0], shifted_out[N-1:1]};
partial_sum <= {partial_sum[(N-1)+8],partial_sum[(N-1)+8:1]} - multiplication_coefficients[multiplication_addresses[address]];
end
end
end
// ==== DA accumulator ====
// ==== output register ====
always_ff @(posedge ck, posedge rst)
if(rst)
out <= '0;
else if (output_ready)
out <= {partial_sum[(N-1)+8],partial_sum, shifted_out[N-1:1]};
// ==== output register ====
// ==== address counter ====
always_ff @(posedge ck, posedge rst)
if(rst)
address <= '0;
else if(input_ready)
address <= '0;
else if(count)
address <= address + 1;
// ==== address counter ====
// === state machine to control the MAC ====
always_ff @(posedge ck, posedge rst)
begin: SEQ
if(rst)
state <= waiting;
else
state <= next_state;
end: SEQ
always_comb
begin: COM
load = '0;
reset_accumulator = '0;
output_ready = '0;
compute = '0;
count = '0;
next_state = state;
unique case (state)
waiting : begin
reset_accumulator = '1;
if(input_ready)
next_state = loading;
end
loading : begin
load = '1;
next_state = processing;
end
processing : begin
compute = '1;
count = '1;
if(address < N-1)
begin
next_state = processing;
end
else
next_state = saving;
end
saving : begin
output_ready = '1;
next_state = waiting;
end
default : next_state = waiting;
endcase
end: COM
// ==== state machine to control the FIR ====
endmodule
\ No newline at end of file
This diff is collapsed.
module DA_test;
timeunit 1ns;
timeprecision 100ps;
logic signed [15:0] in [0:15] = '{2,5,123,345,123,5,10,2342,344,22,234,543,23,65,1111,54};
logic input_ready, ck, rst;
logic signed [39:0] out;
logic output_ready;
const int input_frequency = 5000;
DA_MAC #(.BW(DA_LUT::BW), .N(DA_LUT::N)) DA (.*);
// clock generator
// generates a 1 MHz clock
initial
begin
ck = '0;
forever #500ns ck = ~ck;
end
// generate sample strobe at sample rate of 40kHz
always
begin
#24us input_ready = '1;
#1us input_ready = '0;
end
initial
begin
rst = '0;
#10ns rst = '1;
#10ns rst = '0;
end
endmodule
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment