rom 개념을 이용한 ∑Ai*Bi 두 데이터의 곱셈.
A값 10개와 B값 10개를 dat파일에서 읽어온다. 첨부파일이 work space를 참고할 것.
<hw.v>
module hw7 (
clock , // Clock input of the design
reset , // active high, synchronous Reset input
enable, enable2, wen, // Active high enable signal for counter
reg_a, reg_b, // rom에서 받아올 port
mult_cnt, mult_sum_cnt, // 곱셈 용 카운터, ∑용 카운터
mult, mult_sum, //곱하기용
dis_cnt
); // End of port list
//-------------Parameters-----------------------------
parameter depth = 10;
parameter width = 16;
parameter cnt_bit = 4; // 카운터 비트수, 자료량에 따라 결정 됨. log_2[자료량]의 정수화 올림 -> 엑셀 수식 :ROUNDUP(LOG(10,2),0)
//-------------Input Ports-----------------------------
input clock ;
input reset ;
input enable, enable2, wen ; // enable용
input [width-1:0]reg_a ; //rommemb에서 받아올 포트
input [width-1:0]reg_b ; //rommemb에서 받아올 포트
input dis_cnt; //rommemb에서 받아올 포트
//-------------Output Ports----------------------------
output [cnt_bit-1:0] mult_cnt;
output [cnt_bit-1:0] mult_sum_cnt;
output [width*2-1:0] mult; // 곱한 값
output [width*2+cnt_bit:0] mult_sum; // 곱해서 더한 값
//-------------Input ports Data Type-------------------
// By rule all the input ports should be wires
wire clock ;
wire reset ;
wire enable, enable2, wen ;
wire [width-1:0]reg_a;
wire [width-1:0]reg_b;
wire [cnt_bit-1:0]dis_cnt;
//-------------Output Ports Data Type------------------
// Output port can be a storage element (reg) or a wire
reg [cnt_bit-1:0] mult_cnt;
reg [cnt_bit-1:0] mult_sum_cnt;
reg [width*2-1:0] mult;
reg [width*2-1:0] mult_list[15:0]; // 곱한 값 저장
reg [width*2+cnt_bit:0] mult_sum; // 곱한 것을 모두 더한 reg
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
always @ (posedge clock)
begin : resetting // Block Name
if (reset == 1) begin//
mult_cnt = 0;
mult_sum_cnt=0;
mult = 0;
mult_sum = 0;
end
end // reset
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
always @ (clock)
begin : multiple // Block Name
if (enable == 1) begin//
mult_list[dis_cnt] <= reg_a * reg_b;
end
end // multiplication
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
always @ (posedge clock)
begin : mult_store // Block Name
if (enable2 == 1 && mult_cnt < depth) begin//
mult <= mult_list[mult_cnt];
mult_cnt <= mult_cnt+1;
mult_sum_cnt <= mult_cnt;
end
end // mult_store
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
always @ (posedge clock)
begin : SOSOMR // Block Name
if (wen == 1) begin//
mult_sum <= mult_list[mult_sum_cnt] + mult_sum;
end
end // Sum of Storing of muliplication results.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
endmodule
<rommemb.v>
module rom_memb(
clock, reset,
reg_a, reg_b, dis_cnt
);
parameter width = 16;
parameter depth = 10;
input clock, reset;
output [width-1:0]reg_a ; //rommemb에서 받아올 포트
output [width-1:0]reg_b ; //rommemb에서 받아올 포트
output [3:0]dis_cnt; //rommemb에서 받아올 포트
reg [3:0] romcounter;
reg [3:0] dis_cnt;
reg [width-1:0] reg_av [depth-1:0]; //dat를 저장할 reg
reg [width-1:0] reg_bv [depth-1:0]; //dat를 저장할 reg
reg [width-1:0] reg_a, reg_b; //input port로 넘겨줄 reg
wire clock;
integer i;
always @ (posedge clock) begin
if(reset==1) begin
romcounter =0;
$readmemb("reg_av.dat", reg_av);
$readmemb("reg_bv.dat", reg_bv);
for(i=0; i<depth; i=i+1) begin
$display("reg_av [%0d] = %b", i, reg_av[i]);
$display("reg_bv [%0d] = %b", i, reg_bv[i]);
end // for end
end // if_reset end
end // always end
always @ (posedge clock) begin
if(romcounter<4'b1010) begin
reg_a <= reg_av[romcounter];
reg_b <= reg_bv[romcounter];
romcounter <= romcounter+1;
dis_cnt <= romcounter;
end
end
endmodule
<rom_memb_tb.v>
module rom_memb_tb;
parameter depth = 10;
parameter width = 16;
reg clock, reset, enable, enable2, wen;
wire [15:0] reg_a;
wire [15:0] reg_b;
wire [3:0] dis_cnt;
initial begin
clock = 1;
reset = 0;
enable = 0;
enable2 = 0;
wen = 0;
#5reset = 1; // Assert the reset
#50 reset = 0; // De-assert the reset
enable = 1; // Teading of rom's data(RORSD)
#50 enable2 =1; // Storing of mulitplication results(SOMR)
#50 wen = 1; // Sum of SOMR
#450 enable = 0; // Terminate RORSD
#50 enable2 =0; // Terminate SOMR
wen = 0; // Terminate SOSOMR
#50 $finish; // Terminate simulation
end
always begin
#25 clock = ~clock; // Toggle clock every 25 ticks 25Mhz
end
rom_memb
#(
.depth(10),
.width(16))
rom (
.clock(clock),
.reset(reset),
.reg_a(reg_a),
.reg_b(reg_b),
.dis_cnt(dis_cnt));
hw7
hw7 (
.clock(clock),
.reset(reset),
.enable(enable),
.enable2(enable2),
.wen(wen),
.reg_a(reg_a),
.reg_b(reg_b),
.dis_cnt(dis_cnt)
);
endmodule
댓글 달기