2024.9.10 수업날
< bcd_fnd >
이번에는 저번에 만들었던 Fnd 출력 모듈에서 결과값을 10진수로 표시하는 IP를 만들어본다.
Verilog 수업할때 만들었던 Fnd_cntr 모듈 밑에 아래와 같이 코드를 추가한다.
Block Design에서 IP를 만들기 전에 Basys3 에서 테스트 하기 위해 Verilog 수업할 때 만들었던 .xdc을 아래와 같이 수정한다.
테스트를 완료했으면 create and package new ip를 생성한다.
Add Design Sources에서 아래와 같이 추가해주고, 아래의 Copy 부분을 체크한다.
그리고 아래와 같이 myip_bcd_fnd_cntr_v1_0S00_AXI 모듈(slave 모듈)을 수정한다.
다음으로 아래와 같이 myip_bcd_fnd_cntr_v1_0 모듈(top 모듈)을 수정한다.
Package IP에서 좌측의 항목이 모두 초록색 체크표시가 된 것을 확인한 후 하단의 Package IP를 클릭한다.
다음으로 Block Design에서 Create Block Design을 하여 새로 만든다.
기본적으로 만들어야하는 부분까지 block을 만들어주고 myip_bcd_fnd_cntr_v10을 추가한다.
출력단 추가하기
bcd_fnd_wrapper로 만든 후에 bitstream을 실행한다. 그리고 .xsa를 만든다.
vitis 진행 순서
Mblaze_bcd_fnd_app_system -> hello.c 소스코드
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#define FND_BASEADDR XPAR_MYIP_BCD_FND_CNTR_0_S00_AXI_BASEADDR
int main()
{
init_platform();
print("Start!\n");
volatile unsigned int *FND_CNTR = (volatile unsigned int)FND_BASEADDR;
FND_CNTR[0] = 12;
FND_CNTR[1] = 0;
while(1){
FND_CNTR[1] ^= 1;
print("Hello World\n");
MB_Sleep(1000);
}
cleanup_platform();
return 0;
}
< stopwatch(myip) >
이번에는 Verilog 수업때 만들었던 stopwatch 모듈을 IP로 만들어서 vitis로 제어하는 것을 해본다.
stopwatch 모듈 밑에 ip를 만들기 위한 코드를 아래와 같이 추가해준다.
stop_watch_reg 모듈
//////////////////////////////////////////////////////////////// 2024.9.10
////////////////////////////// SoC에서 ip 추가하기 위한 모듈
module stop_watch_reg(
input clk, reset_p,
input [1:0] control_reg,
output [3:0] com,
output [7:0] seg_7);
wire start_stop, lap, lap_pedge;
assign {start_stop, lap} = control_reg;
edge_detector_p ed_div(
.clk(clk), .reset_p(reset_p),
.cp(lap), .p_edge(lap_pedge));
wire clk_start;
assign clk_start = start_stop ? clk : 0;
wire clk_usec, clk_msec, clk_sec, clk_min;
clock_div_100 usec_clk(
.clk(clk_start), .reset_p(reset_p),
.cp_div_100(clk_usec));
clock_div_1000 msec_clk(
.clk(clk_start), .reset_p(reset_p),
.clk_source(clk_usec),
.cp_div_1000_nedge(clk_msec));
clock_div_1000 sec_clk(
.clk(clk_start), .reset_p(reset_p),
.clk_source(clk_msec),
.cp_div_1000_nedge(clk_sec));
wire [3:0] sec1, sec10, min1, min10;
clock_div_60 min_clk(
.clk(clk_start), .reset_p(reset_p),
.clk_source(clk_sec),
.cp_div_60_nedge(clk_min));
counter_bcd_60 counter_sec(
.clk(clk), .reset_p(reset_p),
.clk_time(clk_sec),
.bcd1(sec1), .bcd10(sec10));
counter_bcd_60 counter_min(
.clk(clk), .reset_p(reset_p),
.clk_time(clk_min),
.bcd1(min1), .bcd10(min10));
// 랩 기능 구현 추가부분
wire [15:0]cur_time ;
assign cur_time = {min10, min1, sec10, sec1};
reg [15:0] lap_time;
always @(posedge clk or posedge reset_p) begin
if(reset_p)lap_time = 0;
else if(lap_pedge) lap_time = cur_time;
end
wire [15:0] value;
assign value = lap ? lap_time : cur_time;
fnd_4digit_cntr fnd(clk, reset_p, value, seg_7, com);
endmodule
다음으로 새로운 Block Design을 생성한다.
Create and Package New IP를 설정하는 과정에서 아래의 체크박스에 표시한다.
edit_myip 진행 순서
slave 모듈 수정해야 할 곳
top 모듈 수정해야 할 곳
체크 표시 확인 후 Package IP 클릭
Sources에서 warpper로 만든 후 bitstream 실행한다.
만약 Block Diagram에서 수정사항이 있으면 수정한 Block Diagram에서 우클릭을 하여 Wrapper를 새로 갱신한다.
다음으로 .xsa 파일 생성
vitis 진행 순서
Mblaze_stopwatch_app -> helloworld.c 소스코드
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#define STOPWATCH_BASEADDR XPAR_MYIP_STOPWATCH_0_S00_AXI_BASEADDR
int main()
{
init_platform();
print("Start!\n");
volatile unsigned int *stopwatch_instance = (volatile unsigned int)STOPWATCH_BASEADDR;
xil_printf("Sanity check : %x \n", stopwatch_instance[7]); // 무결성 체크
while(1){
stopwatch_instance[0] = 0b10;
print("Hello World!\n");
MB_Sleep(1000);
}
cleanup_platform();
return 0;
}
bcd_fnd, stopwatch(myip) 끝!