Created
May 5, 2016 10:30
-
-
Save mkatsimpris/703c1f9764a162117583c3f12b65e5df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding=utf-8 | |
from myhdl import * | |
from math import * | |
from ram import * | |
from myhdl.conversion import * | |
class buf_fifo_int_in(object): | |
def __init__(self,pixel_bits = 24): | |
self.pixel_bits=pixel_bits | |
"""HOST PROG""" | |
self.img_size_x=Signal(intbv(0)[16:]) | |
self.img_size_y=Signal(intbv(0)[16:]) | |
self.sof=Signal(bool(0)) | |
"""HOST DATA""" | |
self.iram_wren=Signal(bool(0)) | |
self.iram_wdata=Signal(intbv(0)[pixel_bits:]) | |
"""FDCT""" | |
self.fdct_fifo_rd=Signal(bool(0)) | |
class buf_fifo_int_out(object): | |
def __init__(self,pixel_bits = 24): | |
self.pixel_bits=pixel_bits | |
"""HOST DATA""" | |
self.fifo_almost_full=Signal(bool(0)) | |
"""FDCT""" | |
self.fdct_fifo_q=Signal(intbv(0)[pixel_bits:]) | |
self.fdct_fifo_hf_full=Signal(bool(0)) | |
def buf_fifo(in_sig,out_sig,clk,rst,extra_lines,pixel_bits,num_lines,max_line_width): | |
num_lines = 8 + extra_lines | |
pixel_cnt,line_cnt=[Signal(intbv(0)[16:]) for _ in range(2)] | |
ramq,ramd=[Signal(intbv(0)[pixel_bits:]) for _ in range(2)] | |
ramenw=Signal(bool(0)) | |
ramwaddr,ramraddr,ramwaddr_d1=[Signal(intbv(0)[ceil(log(max_line_width*num_lines,2)):]) for _ in range(3)] | |
pix_inblk_cnt,pix_inblk_cnt_d1=[Signal(intbv(0)[4:]) for _ in range(2)] | |
line_inblk_cnt=Signal(intbv(0)[3:]) | |
read_block_count,read_block_count_d1,write_block_cnt=[Signal(intbv(0)[13:]) for _ in range(3)] | |
ramaddr_int,raddr_base_line=[Signal(intbv(0)[(16 + log(num_lines,2)):]) for _ in range(2)] | |
raddr_tmp=Signal(intbv(0)[16:]) | |
line_lock,memwr_line_cnt,memrd_line=[Signal(intbv(0)[log(num_lines,2):]) for _ in range(3)] | |
memrd_offs_cnt=Signal(intbv(0)[(log(num_lines,2)+1):]) | |
wr_line_idx,rd_line_idx=[Signal(intbv(0)[16:]) for _ in range(2)] | |
image_write_end=Signal(bool(0)) | |
sub_ram=RAM(ramq,ramd,ramraddr,ramwaddr_d1,ramenw,clk,log(max_line_width*num_lines,2),pixel_bits) | |
"""Register ram data input""" | |
@always_seq(clk.posedge,rst) | |
def data_reg(): | |
ramd.next=in_sig.iram_wdata | |
ramenw.next=in_sig.iram_wren | |
"""Resolve RAM write address""" | |
@always_seq(clk.posedge,rst) | |
def ram_addr_get(): | |
ramwaddr_d1.next=ramwaddr | |
if in_sig.iram_wren == 1: | |
if pixel_cnt == in_sig.img_size_x -1: | |
pixel_cnt.next=0 | |
wr_line_idx.next=wr_line_idx+1 | |
if wr_line_idx == in_sig.img_size_y: | |
image_write_end.next=1 | |
if memwr_line_cnt == num_lines -1: | |
memwr_line_cnt.next=0 | |
ramwaddr.next=0 | |
else: | |
memwr_line_cnt.next=memwr_line_cnt + 1 | |
ramwaddr.next=ramwaddr + 1 | |
else: | |
pixel_cnt.next = pixel_cnt +1 | |
ramwaddr.next=ramwaddr + 1 | |
if in_sig.sof ==1: | |
pixel_cnt.next=0 | |
ramwaddr.next=0 | |
memwr_line_cnt.next=0 | |
wr_line_idx.next=0 | |
image_write_end.next=0 | |
"""FIFO half full/almost full flag generation""" | |
@always_seq(clk.posedge,rst) | |
def hf_af_flag(): | |
if rd_line_idx + 8 <= wr_line_idx: | |
out_sig.fdct_fifo_hf_full.next=1 | |
else: | |
out_sig.fdct_fifo_hf_full.next=0 | |
out_sig.fifo_almost_full.next=0 | |
if wr_line_idx == rd_line_idx + num_lines - 1: | |
if pixel_cnt >= in_sig.img_size_x -1: | |
out_sig.fifo_almost_full.next=1 | |
elif wr_line_idx > rd_line_idx + num_lines -1: | |
out_sig.fifo_almost_full.next=1 | |
""" memrd_offs_cnt is used for the extra 8 lines to ensure that the block which is read will be in correct position in memory""" | |
"""Read side""" | |
@always_seq(clk.posedge,rst) | |
def read_side(): | |
pix_inblk_cnt_d1.next = pix_inblk_cnt | |
read_block_count_d1.next = read_block_count | |
if in_sig.fdct_fifo_rd == 1: | |
if pix_inblk_cnt == 7: | |
pix_inblk_cnt.next = 0 | |
if line_inblk_cnt == 7 : | |
line_inblk_cnt.next=0 | |
if read_block_count == in_sig.img_size_x//num_lines -1: | |
read_block_count.next=0 | |
rd_line_idx.next = 0 | |
if memrd_offs_cnt + 8 >= num_lines - 1: | |
memrd_offs_cnt.next = memrd_offs_cnt + 8 - num_lines | |
else: | |
memrd_offs_cnt.next = memrd_offs_cnt + 8 | |
else: | |
read_block_count.next=read_block_count + 1 | |
else: | |
line_inblk_cnt.next=line_inblk_cnt + 1 | |
else: | |
pix_inblk_cnt.next = pix_inblk_cnt + 1 | |
if memrd_offs_cnt + line_inblk_cnt > num_lines -1: | |
memrd_line.next=memrd_offs_cnt + line_inblk_cnt - num_lines | |
else: | |
memrd_line.next=memrd_offs_cnt + line_inblk_cnt | |
if in_sig.sof==1: | |
memrd_line.next=0 | |
memrd_offs_cnt.next=0 | |
read_block_count.next=0 | |
pix_inblk_cnt.next=0 | |
pix_inblk_cnt.next=0 | |
line_inblk_cnt.next=0 | |
rd_line_idx.next=0 | |
"""Generate RAM data output""" | |
@always_comb | |
def ram_out(): | |
out_sig.fdct_fifo_q.next = ramq | |
ramraddr.next = ramaddr_int | |
"""Resolve RAM read address""" | |
@always_seq(clk.posedge,rst) | |
def ram_read_addr(): | |
raddr_base_line.next = memrd_line *in_sig. img_size_x | |
raddr_tmp.next =concat(read_block_count_d1,"000") + pix_inblk_cnt_d1 | |
ramaddr_int.next = raddr_tmp + raddr_base_line | |
return instances() | |
def convert(): | |
clk=Signal(bool(0)) | |
rst=ResetSignal(val=1,active=True,async=False) | |
inputs=buf_fifo_int_in() | |
outputs=buf_fifo_int_out() | |
""" | |
inst=buf_fifo(inputs,outputs,clk,rst,0,24,8,640) | |
inst.convert(hdl='Verilog') | |
analyze.simulator='iverilog' | |
complcache_start_auto_complete)[<64;150;24M | |
assert inst.analyze_convert() == 0 | |
""" | |
toVHDL(buf_fifo,inputs,outputs,clk,rst,0,24,8,640) | |
analyze.simulator='ghdl' | |
analyze(buf_fifo,inputs,outputs,clk,rst,0,24,8,640) | |
#convert() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding=utf-8 | |
from myhdl import * | |
@block | |
def RAM(dout, din, raddr,waddr, we, clk,addr_width=8, data_width=24): | |
""" Ram model """ | |
mem = [Signal(intbv(0)[data_width:]) for i in range(int(2**addr_width))] | |
read_addr=Signal(intbv(0)[addr_width:]) | |
@always_comb | |
def out(): | |
dout.next=mem[read_addr] | |
@always(clk.posedge) | |
def write(): | |
read_addr.next=raddr | |
if we: | |
mem[waddr].next = din | |
return instances() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding=utf-8 | |
from myhdl import * | |
from random import randrange | |
from buf_fifo import * | |
from myhdl.conversion import * | |
extra_lines=0 | |
pixel_bits=24 | |
num_lines=8 | |
img_size_x=16 | |
max_line_width=img_size_x | |
img_size_y=16 | |
def test(): | |
global extra_lines,pixel_bits,num_lines,max_line_width,img_size_x,img_size_y | |
#test_data=(Signal(intbv(randrange(0,2**pixel_bits-1))[pixel_bits:]) for _ in range(num_lines*max_line_width)) | |
test_data=tuple([randrange(0,2**pixel_bits - 1) for _ in range(num_lines * max_line_width)]) | |
clk = Signal(bool(0)) | |
rst = ResetSignal(1, active=True, async=False) | |
inputs = buf_fifo_int_in() | |
outputs = buf_fifo_int_out() | |
dut = buf_fifo( | |
inputs, | |
outputs, | |
clk, | |
rst, | |
extra_lines, | |
pixel_bits, | |
num_lines, | |
max_line_width) | |
@instance | |
def clkgen(): | |
while True: | |
yield delay(10) | |
clk.next = not clk | |
@instance | |
def reset_on_start(): | |
rst.next=1 | |
yield clk.negedge | |
rst.next=0 | |
@instance | |
def stimulus(): | |
yield clk.negedge | |
yield clk.negedge | |
"""TEST WRITE""" | |
inputs.iram_wren.next=1 | |
inputs.sof.next=1 | |
inputs.img_size_x.next=img_size_x | |
inputs.img_size_y.next=img_size_y | |
yield clk.negedge | |
inputs.sof.next=0 | |
for i in range(num_lines*max_line_width): | |
inputs.iram_wdata.next=test_data[i] | |
#print("Write %d ==> %d"%(i,test_data[i])) | |
yield clk.negedge | |
assert outputs.fifo_almost_full == 1 | |
"""TEST READ""" | |
inputs.iram_wren.next=0 | |
inputs.fdct_fifo_rd.next=1 | |
"""WAIT 4 CLOCKS FOR READ LATENCY AND READ IN THE 5TH CLOCK POSEDGE""" | |
for i in range(4): | |
yield clk.posedge | |
for i in range(num_lines * max_line_width): | |
yield clk.posedge | |
#print("Read %d ==> %d"%(i,outputs.fdct_fifo_q)) | |
#print("%s" % outputs.fdct_fifo_q) | |
raise StopSimulation() | |
return dut,stimulus,clkgen,reset_on_start | |
def test_module(): | |
global extra_lines,pixel_bits,num_lines,max_line_width | |
clk = Signal(bool(0)) | |
rst = ResetSignal(1, active=True, async=False) | |
inputs = buf_fifo_int_in() | |
outputs = buf_fifo_int_out() | |
analyze.simulator=verify.simulator="iverilog" | |
assert verify(test) == 0 | |
def testbench(): | |
testbench = traceSignals(test) | |
#testbench=test() | |
sim=Simulation(testbench) | |
sim.run() | |
if __name__ == '__main__': | |
testbench() | |
test_module() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment