Skip to content

Instantly share code, notes, and snippets.

@mkatsimpris
Created May 5, 2016 10:30
Show Gist options
  • Save mkatsimpris/703c1f9764a162117583c3f12b65e5df to your computer and use it in GitHub Desktop.
Save mkatsimpris/703c1f9764a162117583c3f12b65e5df to your computer and use it in GitHub Desktop.
#!/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()
#!/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()
#!/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