Wednesday, February 29, 2012

verilog code for Serial ALU

//alu module

`timescale 1ns/1ns
module alu(clk, rst, ina, inb, ins_reg, q_out, enable_alu);
input clk, rst, enable_alu;
input [7:0] ina;
input [7:0] inb;
input [2:0] ins_reg;
output q_out;
//output [7:0] rega, regb;
//output carry, borrow;
//reg [7:0] q_out;
reg [7:0] rega, regb;
reg carry, borrow;
reg temp;

always @(posedge clk or negedge rst)

begin
if(!rst)
begin
rega = 8'd0; regb = 8'd0;
end

else if(enable_alu)
begin
rega <= ina; regb <= inb;
end
else
begin
rega <= rega >> 1; regb <= regb >> 1;
end
end
always @(posedge clk or negedge rst)

begin

if(!rst)
begin
temp = 1'b0; carry = 1'b0; borrow = 1'b0;
end

else if(enable_alu == 1'b0)

case(ins_reg)
3'd0 : temp = ~rega[0];

3'd1 : temp = ~regb[0];

3'd2 : {borrow,temp} = rega[0]-regb[0];

3'd3 : {carry,temp} = rega[0] + regb[0];

3'd4 : temp = rega[0] & regb[0];

3'd5 : temp = rega[0] | regb[0];

3'd6 : temp = ~rega[0] + ~regb[0];

3'd7 : temp = ~rega[0] - ~regb[0];

default : temp = 1'b0;
endcase

end
/*always @(posedge clk or negedge rst)

begin

if(!rst)
q_out <= 8'd0;
else*/
assign q_out = temp;

endmodule


//load_reg

`timescale 1ns/1ns
module load_reg( clk, rst, sin, ins_reg, rega, regb, en_ins, ena, enb);
input clk,rst,sin;
input en_ins, ena, enb;
output [2:0] ins_reg;
output [7:0] rega, regb;
reg [2:0] ins_reg;
//reg [2:0] shift_reg;
reg [7:0] rega, regb;

always @(posedge clk or negedge rst)
begin
if(!rst)
begin
rega = 8'd0; regb = 8'd0; ins_reg = 3'd0;
end

else if(en_ins)
begin
ins_reg[2:0] = {sin,ins_reg[2:1]};
end

else if(ena)
begin
rega[7:0] = {sin, rega[7:1]};
end
else if(enb)
begin
regb[7:0] = {sin, regb[7:1]};
end

end


endmodule

//control_alu module

`timescale 1ns/1ns
module controlalu(clk, rst, en_ins, ena, enb, enable_alu, data_valid, out_valid);
input clk, rst, data_valid;
output en_ins, ena, enb, enable_alu , out_valid;
reg en_ins, ena, enb, enable_alu, out_valid;
reg [8:0] count;

parameter [2:0] s1 = 3'b001;
parameter [2:0] s2 = 3'b010;
parameter [2:0] s3 = 3'b011;
parameter [2:0] s4 = 3'b100;
parameter [2:0] s5 = 3'b101;


reg [2:0] present_state;
reg [2:0] next_state;

always @(posedge clk or negedge rst)
begin
if(!rst)
begin
count <= 8'd0; out_valid <= 1'b0; enable_alu <= 1'b0; en_ins <= 1'b0; ena <= 1'b0; enb <= 1'b0;
end
else
count <= count + 1;

end

always @(posedge clk or negedge rst)
begin
if(!rst)
present_state <= s1;
else
present_state <= next_state;
end


always @(present_state or count)
begin

case(present_state)

s1: begin
if(data_valid == 1'b0)
next_state = s1;

else
next_state = s2;
//enable_alu = 1'b0;
end



s2: begin
if(count == 8'd5 || count == 8'd15)
begin
en_ins = 1'b1;
next_state = s2;
end
else if(count == 8'd25)
begin
en_ins = 1'b1;
next_state = s3;
end
else
en_ins = 1'b0;

//enable_alu = 1'b0;
end


s3: begin
if(count == 8'd35 || count == 8'd45 || count == 8'd55 || count == 8'd65 || count == 8'd75 || count == 8'd85 || count ==
8'd95 || count == 8'd105)
begin
en_ins = 1'b0;
ena = 1'b1;
next_state = s3;

end

else if(count == 8'd106)
begin
en_ins = 1'b0;
ena = 1'b0;
enb = 1'b0;
next_state = s4;
end

else
begin
en_ins = 1'b0;
ena = 1'b0;
end
//enable_alu = 1'b0;
end


s4: begin
if(count == 8'd115 || count == 8'd125 || count == 8'd135 || count == 8'd145 || count == 8'd155 || count == 8'd165 ||
count == 8'd175 || count == 8'd185)
begin
en_ins = 1'b0;
ena = 1'b0;
enb = 1'b1;
next_state = s4;
end

else if(count == 8'd186)
begin
en_ins = 1'b0;
ena = 1'b0;
enb = 1'b0;
enable_alu = 1'b1;
next_state = s5;
end
else
begin
en_ins = 1'b0;
ena = 1'b0;
enb = 1'b0;
enable_alu = 1'b0;
end

end

s5: begin
if(count <= 8'd194)
begin
out_valid = 1'b0;
en_ins = 1'b0;
ena = 1'b0;
enb = 1'b0;
enable_alu = 1'b0;
next_state = s1;
end
else
next_state = s5;
out_valid = 1'b1;
end
endcase

end
endmodule


//serial_alu_top module

`timescale 1ns/1ns
module serialalu_top(clk, rst, data_valid, sin, output_valid, sout);
input clk, rst, data_valid, sin;
output sout,output_valid;
wire [2:0]ins_register;
wire [7:0]register_a;
wire [7:0]register_b;
wire enable_ins, enable_a, enable_b, enable_alu;

load_reg load(.clk(clk), .rst(rst), .sin(sin), .ins_reg(ins_register), .rega(register_a), .regb(register_b),
.en_ins(enable_ins), .ena(enable_a), .enb(enable_b));


alu a1(.clk(clk), .rst(rst), .ina(register_a), .inb(register_b), .ins_reg(ins_register), .q_out(sout), .enable_alu(enable_alu));


controlalu c1(.clk(clk), .rst(rst), .en_ins(enable_ins), .ena(enable_a), .enb(enable_b), .enable_alu(enable_alu),
.data_valid(data_valid), .out_valid(output_valid));

endmodule

//testbench for alu

`timescale 1ns/1ns
module test_alu;
reg clk, rst, enable_alu;
reg [7:0] ina;
reg [7:0] inb;
reg [2:0] ins_reg;
wire q_out;

alu al(.clk(clk), .rst(rst), .enable_alu(enable_alu), .ina(ina), .inb(inb), .ins_reg(ins_reg), .q_out(q_out));
initial
begin
clk = 1'b1;
forever #5 clk = ~clk;
end

initial
begin
rst = 1'b0;
#10 rst = 1'b1;
end

task load_alu;
input enable_alu1;
input [7:0] ina1;
input [7:0] inb1;
input [2:0] ins_reg1;
input exp_data;
begin

@(posedge clk)
enable_alu <= enable_alu1;
ina <= ina1;
inb <= inb1;
ins_reg <= ins_reg1;

if(q_out != exp_data)
begin
$display("alu operation failed");
end


end
endtask


initial
begin

load_alu(1'b1, 8'd40, 8'd50, 3'd2, 1'b0);
load_alu(1'b0, 8'd40, 8'd50, 3'd2, 1'b0);



#100 $finish;
end

initial
begin
$recordfile("alu.trn");
$recordvars("depth=0");
end

endmodule


//testbench for load reg

`timescale 1ns/1ns
module test_loadreg;
reg clk, rst, sin;
reg en_ins, ena, enb;
wire [2:0] ins_reg;
wire [7:0] rega, regb;
//parameter cycle = 10;
load_reg ld(.clk(clk), .rst(rst), .sin(sin), .en_ins(en_ins), .ena(ena), .enb(enb), .ins_reg(ins_reg), .rega(rega), .regb(regb));

initial
begin
clk = 1'b1;
forever #5 clk = ~clk;
end

initial
begin
rst = 1'b0;
#10 rst = 1'b1;
end

task load_ins;
input sin1;
input en_ins1;
input [2:0]exp_data;
//output [2:0] ins_reg1;


begin
@(posedge clk)
sin <= sin1;
en_ins <= en_ins1;
//ins_reg <= ins_reg1;
if(ins_reg != exp_data)
begin
$display("ins_load operation failed");
//$finish;
end
end

endtask


task load_rega;
input sin2;
input ena1;
input [7:0]exp_data;
//output [7:0] rega1;

begin
@(posedge clk)
sin <= sin2;
ena <= ena1;
//rega <= rega1;
if(rega != exp_data)
begin
$display("rega operation failed");
//$finish;
end
end

endtask


task load_regb;
input sin3;
input enb1;
input [7:0]exp_data;
//output [7:0] regb1;

begin
@(posedge clk)
sin <= sin3;
enb <= enb1;
//regb <= regb1;
if(regb != exp_data)
begin
$display("regb operation failed");
//$finish;
end
end

endtask

initial
begin

# 10 load_ins (1'b0, 1'b0, 3'b000);
load_ins (1'b1, 1'b1, 3'b100);
load_ins (1'b0, 1'b1, 3'b010);
load_ins (1'b1, 1'b1, 3'b101);
load_ins (1'b1, 1'b0, 3'b101);


end


initial
begin

load_rega (1'b1, 1'b0, 8'd0);
load_rega (1'b0, 1'b0, 8'd0);
load_rega (1'b1, 1'b0, 8'd0);
load_rega (1'b0, 1'b0, 8'd0);


load_rega (1'b0, 1'b1, 8'd0);
load_rega (1'b1, 1'b1, 8'b10000000);
load_rega (1'b0, 1'b1, 8'b01000000);
load_rega (1'b0, 1'b1, 8'b00100000);
load_rega (1'b1, 1'b1, 8'b10010000);
load_rega (1'b1, 1'b1, 8'b11001000);
load_rega (1'b0, 1'b1, 8'b01100100);
load_rega (1'b1, 1'b1, 8'b10110010);
load_rega (1'b1, 1'b0, 8'b10110010);
//load_rega (1'b0, 1'b1);
//load_rega (1'b1, 1'b1);

end


initial
begin

load_regb (1'b1, 1'b0, 8'd0);
load_regb (1'b1, 1'b0, 8'd0);
load_regb (1'b1, 1'b0, 8'd0);
load_regb (1'b1, 1'b0, 8'd0);
load_regb (1'b0, 1'b0, 8'd0);
load_regb (1'b0, 1'b0, 8'd0);
load_regb (1'b1, 1'b0, 8'd0);
load_regb (1'b1, 1'b0, 8'd0);
load_regb (1'b0, 1'b0, 8'd0);
load_regb (1'b0, 1'b0, 8'd0);
load_regb (1'b0, 1'b0, 8'd0);
load_regb (1'b0, 1'b0, 8'd0);
load_regb (1'b1, 1'b1, 8'b10000000);
load_regb (1'b0, 1'b1, 8'b01000000);
load_regb (1'b1, 1'b1, 8'b10100000);
load_regb (1'b1, 1'b1, 8'b11010000);
load_regb (1'b1, 1'b1, 8'b11101000);
load_regb (1'b0, 1'b1, 8'b01110100);
load_regb (1'b0, 1'b1, 8'b00111010);
load_regb (1'b0, 1'b0, 8'b00111010);
//load_rega (1'b0, 1'b1);
//load_rega (1'b1, 1'b1);


#100 $finish;
end

initial
begin
$recordfile("load_reg.trn");
$recordvars("depth=0");
end

endmodule


//testbench for serial_alu final

`timescale 1ns/1ns
module test_serialalu;
reg clk, rst, data_valid, sin;
wire output_valid, sout;

serialalu_top ser(.clk(clk), .sin(sin), .rst(rst), .data_valid(data_valid), .output_valid(output_valid), .sout(sout));


initial
begin
clk = 1'b1;
forever #5 clk = ~clk;
end

initial
begin
rst = 1'b0;
#10 rst = 1'b1;
end

task load_inputs;
input data_valid2;
input sin2;

input exp_data;

begin
@(posedge clk)
data_valid <= data_valid2;
sin <= sin2;
//output_valid <= output_valid2;
if(sout != exp_data)
begin
$display("sout operation failed");

end
end

endtask

initial
begin
load_inputs (1'b0, 1'b1, 1'b0);
# 40 load_inputs(1'b1, 1'b1, 1'b1);
#100 load_inputs(1'b1, 1'b0, 1'b0);
#100 load_inputs(1'b1, 1'b1, 1'b0);

#100 load_inputs(1'b1, 1'b1, 1'b1);
#100 load_inputs(1'b1, 1'b1, 1'b1);
#100 load_inputs(1'b1, 1'b0, 1'b0);
#100 load_inputs(1'b1, 1'b0, 1'b0);
#100 load_inputs(1'b1, 1'b1, 1'b1);
#100 load_inputs(1'b1, 1'b0, 1'b0);
#100 load_inputs(1'b1, 1'b1, 1'b1);
#100 load_inputs(1'b1, 1'b0, 1'b0);

#100 load_inputs(1'b1, 1'b1, 1'b1);
#100 load_inputs(1'b1, 1'b1, 1'b1);
#100 load_inputs(1'b1, 1'b0, 1'b0);
#100 load_inputs(1'b1, 1'b1, 1'b1);
#100 load_inputs(1'b1, 1'b0, 1'b0);
#100 load_inputs(1'b1, 1'b0, 1'b0);
#100 load_inputs(1'b1, 1'b1, 1'b1);
#100 load_inputs(1'b1, 1'b0, 1'b0);
load_inputs(1'b0, 1'b0, 1'b1);
load_inputs(1'b0, 1'b0, 1'b1);
load_inputs(1'b0, 1'b0, 1'b0);
load_inputs(1'b0, 1'b0, 1'b0);
load_inputs(1'b0, 1'b0, 1'b0);
load_inputs(1'b0, 1'b0, 1'b0);
load_inputs(1'b0, 1'b0, 1'b1);
load_inputs(1'b0, 1'b0, 1'b0);

#1000 $finish;
end

initial
begin
$sdf_annotate("../syn/serialalu_top.sdf");
end


initial
begin
$recordfile ("serialalu_top.trn");
$recordvars ("depth = 0");
end

endmodule





No comments:

Post a Comment

Popular Posts