Uploaded by Mani Vannan

`timescale 1ns 1ps

advertisement
`timescale 1ns / 1ps
module DSP(CLK,RST,A,B,OPCODE,DATA_id,REQUEST_COUNTER,PROCESS_COUNTER,OUTA,OUT_MAC,OUT_SHIFT_ID);
input [15:0]A,B;
input CLK,RST;
input [3:0]OPCODE;
input [4:0]DATA_id;
output reg[31:0]OUTA, OUT_MAC;
output reg[15:0]OUT_SHIFT_ID;
reg [40:0]STACK_in;
wire [31:0]OUT_a,OUT_mac;
wire [15:0]OUT_sid;
wire [40:0]CONTROL_out, RAM_out, EX_out, STACK_out;
wire [48:0]ADDRESS_out;
wire [7:0]wr_add, rd_add;
wire [3:0]DSP_in, DSP_sel;
wire [2:0]ALU_sel, ALU_in;
wire [4:0]PROCESS_COMPLETE_ALU, PROCESS_COMPLETE_DSP, DATA_WRITE_COMPLETE;
wire wr_en, rd_en;
reg [4:0]PROCESS_COMPLETE;
output reg [4:0] REQUEST_COUNTER,PROCESS_COUNTER;
reg [4:0]DATA_id_old,PROCESS_old;
reg STATE;
reg COUNT;
reg CLK_2;
always @(posedge CLK)
begin
if(RST) begin {COUNT,STATE} <=0; CLK_2<=CLK; end
else
begin case(STATE)
1'b0:begin
if(COUNT<1) begin COUNT<=COUNT+1'b1; CLK_2<=1'b1; STATE<=1'b0; end
else begin CLK_2<=1'b0; STATE<=1; COUNT<=0; end
end
1'b1:begin
if(COUNT<1) begin COUNT<=COUNT+1'b1; CLK_2<=1'b0; STATE<=1'b1; end
else begin CLK_2<=1'b1; STATE<=0; COUNT<=0; end
end endcase
end
end
always @(posedge CLK)
begin
if(RST)
begin
{DATA_id_old,PROCESS_old,REQUEST_COUNTER,PROCESS_COUNTER} = 0;
end
else
begin
if(DATA_id_old!=DATA_id) begin
REQUEST_COUNTER = REQUEST_COUNTER + 5'b00001;
DATA_id_old = DATA_id;
end
else begin
REQUEST_COUNTER = REQUEST_COUNTER;
DATA_id_old = DATA_id_old;
end
if(PROCESS_old!=PROCESS_COMPLETE) begin
PROCESS_COUNTER = PROCESS_COUNTER + 5'b00001;
PROCESS_old = PROCESS_COMPLETE;
end
else begin
PROCESS_COUNTER = PROCESS_COUNTER;
PROCESS_old = PROCESS_old;
end
end end
always @ (posedge CLK) begin
if(RST) {OUTA,OUT_MAC,OUT_SHIFT_ID,STACK_in,PROCESS_COMPLETE} = 0;
else begin STACK_in = {A,B,OPCODE,DATA_id};
OUTA=OUT_a;
OUT_MAC=OUT_mac;
OUT_SHIFT_ID=OUT_sid;
PROCESS_COMPLETE = PROCESS_COMPLETE_ALU + PROCESS_COMPLETE_DSP;
end end
STACK ST(CLK, RST, STACK_in, STACK_out);
ADD_GEN ADGN(CLK, RST, STACK_out, ADDRESS_out);
CONTROL CTRL(CLK, RST, ADDRESS_out, CONTROL_out, wr_en, wr_add, DATA_WRITE_COMPLETE);
RAM_BLOCK RB( CLK, CLK_2, RST, CONTROL_out, RAM_out, rd_en, wr_en, rd_add, wr_add, DATA_WRITE_COMPLETE);
EXECUTE EX(CLK_2, RST, RAM_out, PROCESS_COMPLETE, EX_out, DSP_sel, DSP_in, ALU_sel, ALU_in, rd_en, rd_add);
PROGRAM_MEMORY1 PM(CLK_2, RST, EX_out[8:5], ALU_sel, DSP_sel);
ALU A16(EX_out[40:25],EX_out[24:9],EX_out[4:0],OUT_a,PROCESS_COMPLETE_ALU,ALU_in,CLK_2,RST);
DSP_UNIT DSP(EX_out[40:25],EX_out[24:9],OUT_mac,OUT_sid,EX_out[4:0],PROCESS_COMPLETE_DSP,DSP_in,CLK_2,RST);
endmodule
module STACK(CLK,RST,OPCODE_id,STACK_out);
input CLK,RST;
input [40:0]OPCODE_id;
parameter MEMSIZE = 16, WORDSIZE = 41;
integer i;
output reg [40:0]STACK_out;
reg [WORDSIZE-1:0]STACK[MEMSIZE-1:0];
reg [4:0]OPCODE_id_old;
reg [4:0]OPCODE_id_new;
reg [3:0]j;
always @(posedge CLK)
begin
if (RST)
begin for(i=15;i>=0;i=i-1)
begin
STACK[i]=0;
end
OPCODE_id_old = 0; STACK_out=0;
j=0;
OPCODE_id_new=0;
end
else
OPCODE_id_new = OPCODE_id[4:0];
begin
if(OPCODE_id_old != OPCODE_id_new)
begin
for(i=0;i<15;i=i+1)
begin
STACK[i]=STACK[i+1];
end
STACK[15]=OPCODE_id;
OPCODE_id_old = OPCODE_id_new;
end
else OPCODE_id_old = OPCODE_id_old;
end
if(STACK[j]== 41'h0000) j=j+4'b0001;
else
begin
STACK_out=STACK[j]; end end
endmodule
module ADD_GEN(CLK,RST,OPCODE_id,ADD_out);
input CLK,RST;
input [40:0]OPCODE_id;
output reg [48:0]ADD_out;
integer i;
reg [40:0]OPCODE_id_old;
reg [255:0]ADD_id;
reg pointer;
initial
begin
{OPCODE_id_old, ADD_id, ADD_out}=0;
end
always @ (posedge CLK)
begin
if(RST)
begin
{OPCODE_id_old, ADD_id, ADD_out}=0;
end
else if (OPCODE_id_old != OPCODE_id)
begin
pointer=1'b0;
for(i=0;i<=255;i=i+1)
begin
if((ADD_id[i]==1'b0)&&(pointer==1'b0)) begin
ADD_out ={OPCODE_id,i[7:0]};
ADD_id[i] = 1'b1;
OPCODE_id_old = OPCODE_id; pointer=1'b1; end
else
begin
OPCODE_id_old = OPCODE_id_old;
end end
end
end
endmodule
module CONTROL(CLK,RST,DATA_in,DATA_out,wr_en,wr_add,DATA_WRITE_COMPLETE);
input CLK,RST;
input [48:0]DATA_in;
output reg wr_en;
output reg[40:0]DATA_out; output reg[7:0]wr_add;
reg [4:0]OPCODE_id_old; input [4:0]DATA_WRITE_COMPLETE;
always @ (posedge CLK)
begin
if (RST) begin OPCODE_id_old = 0; wr_en = 0; wr_add = 0; DATA_out = 0;
end
else begin
if(OPCODE_id_old != DATA_in[12:8])
begin
wr_en = 1;
wr_add = DATA_in[7:0]; DATA_out = DATA_in[48:8]; OPCODE_id_old = DATA_in[12:8];
end
else if(DATA_WRITE_COMPLETE == DATA_in[12:8])
begin
wr_en = 0; end else
begin
wr_add = wr_add; DATA_out = DATA_out; OPCODE_id_old = OPCODE_id_old;
end
end end
endmodule
module RAM_BLOCK(CLK, CLK_2, RST, DATA_in, DATA_out, rd_en, wr_en, rd_add, wr_add,DATA_WRITE_COMPLETE);
input CLK, CLK_2, RST, rd_en, wr_en;
input wire [7:0]rd_add, wr_add; input [40:0] DATA_in; output reg [40:0] DATA_out;
output reg [4:0] DATA_WRITE_COMPLETE;
reg [15:0]A_in, B_in; wire [15:0]a,b;
reg [3:0] OPCODE_in;
wire [3:0] op;
reg [4:0] OPCODE_id_in;
wire [4:0] op_id,DATA_WRITE_COMPLETE_a;
always @ (posedge CLK) begin
if(RST) DATA_WRITE_COMPLETE<=0;
else begin
DATA_WRITE_COMPLETE<=DATA_WRITE_COMPLETE_a;
{A_in, B_in, OPCODE_in, OPCODE_id_in} <= DATA_in;
end
end
always @ (posedge CLK_2) begin
if(RST) DATA_out <=0;
else begin
DATA_out <= {a,b,op,op_id};
end
end
RAM256 RAM_A(CLK, CLK_2, RST, A_in, a, rd_en, wr_en, rd_add, wr_add);
RAM256 RAM_B(CLK, CLK_2, RST, B_in, b, rd_en, wr_en, rd_add, wr_add);
RAM256_OP RAM_OPCODE(CLK, CLK_2, RST, OPCODE_in, op, rd_en, wr_en, rd_add, wr_add);
RAM256_OP_id RAM_OPCODE_id(CLK, CLK_2, RST, OPCODE_id_in, op_id, rd_en, wr_en, rd_add, wr_add,DATA_WRITE_COMPLETE_a); endmodule
module RAM256(clk, CLK_2, rst, data_in, data_out, rd_en, wr_en, rd_add, wr_add);
input CLK_2, rst, clk, rd_en, wr_en; input [7:0]rd_add, wr_add; input [15:0] data_in; output reg [15:0] data_out; parameter WORDSIZE = 16, MEMSIZE = 256 ; reg[WORDSIZE-1:0]RAM[MEMSIZE-1:0]; integer i;
always @(posedge clk)
begin
if(rst)
begin
for(i=0;i<=255;i=i+1) begin RAM[i]=0; end
end
else begin
if(wr_en==1'b1) RAM[wr_add]=data_in;
else RAM[wr_add]=RAM[wr_add];
end
end
always @ (posedge CLK_2)
begin
if (rst) data_out=0;
else begin
if(rd_en==1'b1) data_out=RAM[rd_add];
else data_out=data_out;
end
end endmodule
module RAM256_OP_id(clk, CLK_2, rst, data_in, data_out, rd_en, wr_en, rd_add, wr_add,DATA_WRITE_COMPLETE);
input CLK_2, rst, clk, rd_en, wr_en; input [7:0]rd_add, wr_add; input [4:0] data_in; output reg [4:0] data_out; parameter WORDSIZE = 5, MEMSIZE = 256 ; reg[WORDSIZE-1:0]RAM[MEMSIZE-1:0]; integer i;
output reg [4:0]DATA_WRITE_COMPLETE;
always @(posedge clk)
begin
if(rst)
begin
DATA_WRITE_COMPLETE =0;
for(i=0;i<=255;i=i+1) begin RAM[i]=0; end end
else
begin
if(wr_en==1'b1)
begin
RAM[wr_add]=data_in;
DATA_WRITE_COMPLETE= RAM[wr_add];
end
else RAM[wr_add] = RAM[wr_add];
end
end
always @ (posedge CLK_2)
begin
if(rst) data_out = 0;
else begin
if(rd_en==1'b1)
begin
data_out=RAM[rd_add];
end
else data_out=data_out;
end
end
endmodule
module RAM256_OP(clk, CLK_2, rst, data_in, data_out, rd_en, wr_en, rd_add, wr_add);
input CLK_2, rst, clk, rd_en, wr_en; input [7:0]rd_add, wr_add; input [3:0] data_in; output reg [3:0] data_out; parameter WORDSIZE = 4, MEMSIZE = 256 ; reg[WORDSIZE-1:0]RAM[MEMSIZE-1:0]; integer i;
always @(posedge clk)
begin
if(rst)
begin
for(i=0;i<=255;i=i+1) begin RAM[i]=0; end
end
else begin
if(wr_en==1'b1) RAM[wr_add]=data_in;
else RAM[wr_add]=RAM[wr_add];
end
end
always @ (posedge CLK_2)
begin
if (rst) data_out=0;
else begin
if(rd_en==1'b1) data_out=RAM[rd_add];
else data_out=data_out;
end
end
endmodule
module EXECUTE(CLK, RST, DATA_in, PROCESS_COMPLETE, DATA_out, SEQ_in, DSP_in, SEL_in, ALU_in, rd_en, rd_add);
input CLK,RST;
input [40:0]DATA_in;
input [3:0]SEQ_in;
input [2:0]SEL_in;
input [4:0]PROCESS_COMPLETE;
output reg [40:0]DATA_out;
output reg [3:0]DSP_in;
output reg [2:0]ALU_in;
output reg rd_en;
output reg [7:0]rd_add;
reg [7:0]i; reg [2:0]STATE;
reg [4:0]DATA_in_old; always @ (posedge CLK)
begin
if (RST)
begin
{i,DATA_out,ALU_in,DSP_in,rd_en,rd_add,DATA_in_old,STATE} = 0;
end
else begin
case (STATE)
3'b000 : begin
rd_en = 1'b1;
rd_add = i; if(DATA_in_old != DATA_in[4:0]) begin
DATA_in_old = DATA_in[4:0]; STATE = 3'b001;
end
else STATE = 3'b000;
end
3'b001 : begin
rd_en = 1'b0;
DATA_out = DATA_in;
ALU_in = SEL_in;
DSP_in = SEQ_in;
if(PROCESS_COMPLETE == DATA_in_old) begin
i=i+8'b00000001;
STATE = 3'b010;
end
else STATE = 3'b001;
end
3'b010 : begin
rd_en = 1'b1;
rd_add=i;
if((DATA_in[4:0] != DATA_in_old)&&(DATA_in[4:0] != 5'b0))
begin DATA_in_old=DATA_in[4:0]; STATE = 3'b001; end
else STATE = 3'b010;
end endcase
end
end
endmodule
module ALU(A,B,OP_id,OUT,PROCESS_COMPLETE,SELECT,CLK,RST);
input CLK,RST;
input [2:0]SELECT;
input [15:0]A,B;
output reg[31:0]OUT;
input [4:0]OP_id;
output reg[4:0]PROCESS_COMPLETE;
wire [20:0]OUTa,OUTs,OUTd;
wire [36:0]OUTm,OUTx;
reg [20:0]A_in;
reg [15:0]B_in;
always @ (posedge CLK)
begin
if(RST)
begin
A_in<=0;
B_in<=0;
PROCESS_COMPLETE<=0;
OUT<=0;
end
else
begin A_in<={A,OP_id};
B_in<=B;
OUT<=OUTx[36:5];
if(SELECT==0) PROCESS_COMPLETE <= 0;
else PROCESS_COMPLETE<=OUTx[4:0]; end
end
ADDER16 ALUA32(A_in,B_in,OUTa);
SUBTRACTOR16 ALUSUB16(A_in,B_in,OUTs);
MULTIPLIER16 ALUM16(A_in,B_in,OUTm);
DIVIDE16 ALUDIV16(A_in,B_in,OUTd);
MUX MUXALU(OUTa,OUTs,OUTd,OUTm,OUTx,SELECT,CLK,RST);
endmodule
module MULTIPLIER16(A,B,OUT);
input [20:0]A;
input [15:0]B;
wire [31:0]OUTx;
output [36:0]OUT;
assign OUTx = A[20:5] * B;
assign OUT = {OUTx,A[4:0]};
endmodule
module ADDER16(A,B,OUT);
input [20:0]A;
input [15:0]B;
wire [15:0]OUTx;
output [20:0]OUT;
assign OUTx = A[20:5] + B;
assign OUT = {OUTx,A[4:0]};
endmodule
module SUBTRACTOR16(A,B,OUT);
input [20:0]A;
input [15:0]B;
wire [15:0]OUTx;
output [20:0]OUT;
assign OUTx = A[20:5] - B;
assign OUT = {OUTx,A[4:0]};
endmodule
module DIVIDE16(A,B,OUT);
input [20:0]A;
input [15:0]B;
wire [15:0]OUTx;
output [20:0]OUT;
assign OUTx = A[20:5] / B;
assign OUT = {OUTx,A[4:0]};
endmodule
module MUX(OUTa,OUTs,OUTd,OUTm,OUT,SELECT,CLK,RST);
input CLK,RST;
input [2:0]SELECT;
input [20:0]OUTa,OUTs,OUTd;
input [36:0]OUTm;
output reg [36:0]OUT; always @ (posedge CLK)
begin
if(RST)
begin
OUT[36:0]<=0;
end
else
begin
case (SELECT)
3'b101: begin OUT[20:0]<=OUTa; OUT[36:21]<=0; end 3'b110: begin OUT[20:0]<=OUTs; OUT[36:21]<=0; end 3'b011: begin OUT<=OUTm; end 3'b111: begin OUT[20:0]<=OUTd; OUT[36:21]<=0; end default: OUT<=OUT; endcase
end
end
endmodule
module DSP_UNIT(A,B,OUT_M,OUT_S_ID,OP_id,PROCESS_COMPLETE,SELECT,CLK,RST);
input [15:0]A,B;
input [4:0]OP_id;
input CLK,RST;
input [3:0]SELECT;
output reg[31:0]OUT_M;
output reg[15:0]OUT_S_ID;
output reg[4:0]PROCESS_COMPLETE;
reg [15:0]Am,Bm,As,Ai;
wire [15:0]OUT_S,OUT_ID;
wire [31:0]OUT_MAC;
reg [3:0]STATE; always @ (posedge CLK)
begin
if(RST) {OUT_M,OUT_S_ID,PROCESS_COMPLETE,Am,Bm,As,Ai,STATE}=0;
else
begin OUT_M=OUT_MAC; case(STATE)
4'b1100: begin
{As,Ai}=0;
{Am,Bm}={A,B};
OUT_S_ID=0;
PROCESS_COMPLETE = OP_id;
STATE=4'b0;
end
4'b0010,4'b0011,
4'b0100,4'b0101,
4'b0110,4'b0111: begin
{Am,Bm,Ai}=0;
As=A;
OUT_M=0;
OUT_S_ID=OUT_S;
PROCESS_COMPLETE = OP_id;
STATE=4'b0;
end
4'b1010,4'b1011 : begin
{Am,Bm,As}=0;
Ai=A;
OUT_M=0;
OUT_S_ID=OUT_ID;
PROCESS_COMPLETE = OP_id;
STATE=4'b0;
end
4'b0000: begin
STATE=SELECT;
if(SELECT==0) PROCESS_COMPLETE = 0;
else PROCESS_COMPLETE = PROCESS_COMPLETE;
end
default: begin
OUT_M=0;
OUT_S_ID=0; end
endcase
end
end
MAC16 MA(Am, Bm, OUT_MAC, CLK, RST);
INT_DEC ID(CLK, RST, Ai, SELECT, B[7:0], OUT_ID);
SHIFTER SH(CLK, RST, As, OUT_S, SELECT);
endmodule
module MAC16(A,B,OUT,CLK,RST);
input CLK,RST;
input [15:0]A,B;
output [31:0]OUT;
wire [31:0]OUT1,OUT2;
MULTIPLIER16M M16(A,B,OUT1);
ADDER32 A32(OUT1,OUT,OUT2);
ACCUMULATOR32 AC32(OUT2,OUT,CLK,RST);
endmodule
module MULTIPLIER16M(A,B,OUT);
input [15:0]A,B;
output [31:0]OUT;
assign OUT = A * B;
endmodule
module ADDER32(A,B,OUT);
input [31:0]A,B;
output [31:0]OUT;
assign OUT = A + B;
endmodule
module ACCUMULATOR32(IN,OUT,CLK,RST);
input CLK,RST;
input [31:0]IN;
output reg[31:0]OUT;
always @ (posedge CLK)
begin
if(RST)
OUT <= 32'b0;
else OUT <= IN;
end endmodule
module SHIFTER(CLK,RST,DATA_in,A,MODE);
input [15:0]DATA_in;
input CLK,RST;
input [3:0]MODE;
output reg [15:0]A;
integer i;
always @(posedge CLK)
begin
if(RST)
begin
{A,i}= 0;
end
else
begin
case(MODE)
4'b0010:begin //ARITHMETIC RIGHT SHIFT
A=DATA_in;
for(i=0;i<15;i=i+1) A[i]=A[i+1];
if(A[14]==1'b1) A[15]=1'b1;
else A[15]=1'b0; end
4'b0011:begin //ARITHMETIC LEFT SHIFT
A=DATA_in;
for(i=15;i>=1;i=i-1) A[i]=A[i-1];
A[0]=1'b0; end 4'b0100:begin //LOGICAL RIGHT SHIFT
A=DATA_in;
for(i=0;i<15;i=i+1) A[i]=A[i+1];
A[15]=1'b0; end 4'b0101:begin //LOGICAL LEFT SHIFT
A=DATA_in; for(i=15;i>=1;i=i-1) A[i]=A[i-1];
A[0]=1'b0; end
4'b0110:begin //BARREL RIGHT SHIFT
A=DATA_in;
for(i=0;i<15;i=i+1) A[i]=A[i+1];
A[15]=DATA_in[0]; end 4'b0111:begin //BARREL RIGHT SHIFT
A=DATA_in; for(i=15;i>=1;i=i-1) A[i]=A[i-1];
A[0]=DATA_in[15]; end default:begin
A=0; end endcase
end
end endmodule
module INT_DEC(CLK,RST,DATA_in,MODE,SAMPLE_RATE,DATA_out);
input [15:0]DATA_in;
input [3:0]MODE;
input CLK,RST;
input [7:0]SAMPLE_RATE;
output reg [15:0] DATA_out;
reg [3:0]STATE;
reg [7:0]A;
reg [15:0]B;
always @(posedge CLK)
begin
if(RST)
begin
{DATA_out,A,B,STATE} = 0;
end
else
begin
case(STATE)
4'b0:begin
STATE=MODE;
end 4'b1011:begin
DATA_out = DATA_in;
STATE=4'b0011;
A=8'b0;
end
4'b0011:begin
DATA_out = 0;
A=A+8'b00000001;
if(A<SAMPLE_RATE) STATE=4'b0011;
else STATE=4'b0;
end 4'b1010:begin
DATA_out = DATA_in;
STATE=4'b1111;
A=8'b0;
B=DATA_in;
end
4'b1111:begin
DATA_out = B;
A=A+8'b00000001;
if(A<SAMPLE_RATE) STATE=4'b1111;
else STATE=4'b0;
end
default:begin
DATA_out = 0;
end endcase
end
end endmodule module PROGRAM_MEMORY1(CLK,RST,PROM_in,ALU_sel,DSP_sel);
input CLK,RST;
input [3:0]PROM_in;
output reg [3:0]DSP_sel;
output reg [2:0]ALU_sel;
always @ (posedge CLK) begin if (RST) {ALU_sel,DSP_sel}<=0; else
begin
case (PROM_in[3:0])
4'b0000 : begin ALU_sel[2:0]<=3'b101; DSP_sel<=0; end //ADDER
4'b0001 : begin ALU_sel[2:0]<=3'b110; DSP_sel<=0; end //SUBTRACTOR
4'b0010 : begin ALU_sel[2:0]<=3'b011; DSP_sel<=0; end //MULTIPLICATION
4'b0011 : begin ALU_sel[2:0]<=3'b111; DSP_sel<=0; end //DIVIDER
4'b0100 : begin DSP_sel[3:0]<=4'b0010; ALU_sel<=0; end //SHIFTER_AR
4'b0101 : begin DSP_sel[3:0]<=4'b0011; ALU_sel<=0; end //SHIFTER_AL
4'b0110 : begin DSP_sel[3:0]<=4'b0100; ALU_sel<=0; end //SHIFTER_LR
4'b0111 : begin DSP_sel[3:0]<=4'b0101; ALU_sel<=0; end //SHIFTER_LL
4'b1000 : begin DSP_sel[3:0]<=4'b0110; ALU_sel<=0; end //BARREL_SHIFTER_R
4'b1001 : begin DSP_sel[3:0]<=4'b0111; ALU_sel<=0; end //BARREL_SHIFTER_L
4'b1010 : begin DSP_sel[3:0]<=4'b1010; ALU_sel<=0; end //INTERPOLATOR
4'b1011 : begin DSP_sel[3:0]<=4'b1011; ALU_sel<=0; end //DECIMATOR
4'b1100 : begin DSP_sel[3:0]<=4'b1100; ALU_sel<=0; end //MAC default : begin DSP_sel[3:0]<=0; ALU_sel<=0; end endcase
end
end
endmodule
Download