Skip to content

Instantly share code, notes, and snippets.

@mkatsimpris
Created May 3, 2016 10:23
Show Gist options
  • Save mkatsimpris/5d8ca41209d2508275bdac08484547e9 to your computer and use it in GitHub Desktop.
Save mkatsimpris/5d8ca41209d2508275bdac08484547e9 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 *
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))
@block
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)[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+1,2)])
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 = ConcatSignal(read_block_count_d1,"000") + pix_inblk_cnt_d1
ramaddr_int.next = raddr_tmp + raddr_base_line
return sub_ram,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')
convert()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment