Guest User

Untitled

a guest
Aug 9th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.04 KB | None | 0 0
  1. """
  2. Quantization Module
  3. ===================
  4.  
  5. In this quantization module, we are dividing our matrix with certain values as per the quantization table to increase the number of
  6. zeros that is used in the compression in the next stages.
  7. However instead of dividing which creates a problem because of non-storage of decimal values as such in a signal,
  8. We are going to multiply the values with the inverse of the values within the matrix.
  9. And give the output for the next stage.
  10.  
  11. """
  12.  
  13. from litex.gen import *
  14. from litex.soc.interconnect.stream import *
  15. from litex.soc.interconnect.csr import *
  16.  
  17. from litejpeg.core.common import *
  18.  
  19. # Building up the quantization table required for the quantization module.
  20. # Must be specified previously.
  21. quant_values=[16, 11, 10, 16, 24, 40, 51, 61,
  22.               12, 12, 14, 19, 26, 58, 60, 55,
  23.               14, 13, 16, 24, 40, 57, 69, 56,
  24.               14, 17, 22, 29, 51, 87, 80, 62,
  25.               18, 22, 37, 56, 68,109,103, 77,
  26.               24, 35, 55, 64, 81,104,113, 92,
  27.               49, 64, 78, 87,103,121,120,101,
  28.               72, 92, 95, 98,112,100,103, 99]
  29.  
  30.  
  31. class Quantization(PipelinedActor, Module):
  32.     def __init__(self):
  33.  
  34.         # Connecting the data to the Test Bench to take the input/give the output.
  35.         # sink = Take the data for the module.
  36.         # source = Show the output specified by the module.
  37.         self.sink = sink = stream.Endpoint(EndpointDescription(block_layout(12)))
  38.         self.source = source = stream.Endpoint(EndpointDescription(block_layout(12)))
  39.  
  40.  
  41.         """
  42.        Quantization ROM
  43.        ================
  44.  
  45.        Storing values of the quantization tables.
  46.        We are storing the inverse of the values in the qunatization table.
  47.        However that lead to a floating point number which is not a migen value.
  48.        Hence we are storing (2**16)/quantization value.
  49.        This provide us appropriate precision for the process.
  50.  
  51.        """
  52.         inverse = Memory(16,2**6)
  53.         invese_write_port = inverse.get_port(write_capable=True)
  54.         inverse_read_port = inverse.get_port(async_read=True)
  55.         self.specials += inverse, inverse_read_port,invese_write_port
  56.  
  57.         for i in range(64):
  58.             self.comb += inverse[i].eq(int((2**16)/quant_values[i]))
  59.  
  60.  
  61.  
  62.         #Collecting the input values from the previous module and store them in a memory.
  63.         data_mem = Memory(12, 64*2)
  64.         data_write_port = data_mem.get_port(write_capable=True)
  65.         data_read_port = data_mem.get_port(async_read=True)
  66.         self.specials += data_mem, data_write_port, data_read_port
  67.  
  68.         block_inc = Signal(1)
  69.         block_count = Signal(6)
  70.  
  71.         write_sel = Signal()
  72.         write_swap = Signal()
  73.         read_sel = Signal(reset=1)
  74.         read_swap = Signal()
  75.         self.sync += [
  76.             If(write_swap,
  77.                 write_sel.eq(~write_sel)
  78.             ),
  79.             If(read_swap,
  80.                 read_sel.eq(~read_sel)
  81.             )
  82.         ]
  83.  
  84.         # write path
  85.         write_clr = Signal()
  86.         write_inc = Signal()
  87.         write_count = Signal(6)
  88.         self.sync += \
  89.             If(write_clr,
  90.                 write_count.eq(0)
  91.             ).Elif(write_inc,
  92.                 write_count.eq(write_count + 1)
  93.             )
  94.  
  95.         self.comb += [
  96.             data_write_port.adr.eq(write_count),
  97.             data_write_port.adr[-1].eq(write_sel),
  98.             data_write_port.dat_w.eq(sink.data),
  99.             data_write_port.we.eq(sink.valid & sink.ready)
  100.         ]
  101.  
  102.         self.submodules.write_fsm = write_fsm = FSM(reset_state="IDLE")
  103.         write_fsm.act("IDLE",
  104.             write_clr.eq(1),
  105.             If(write_sel != read_sel,
  106.                 NextState("WRITE")
  107.             )
  108.         )
  109.         write_fsm.act("WRITE",
  110.             sink.ready.eq(1),
  111.             If(sink.valid,
  112.                 If(write_count == 63,
  113.                     write_swap.eq(1),
  114.                     NextState("IDLE")
  115.                 ).Else(
  116.                     write_inc.eq(1)
  117.                 )
  118.             )
  119.         )
  120.  
  121.         # read path
  122.         read_clr = Signal()
  123.         read_inc = Signal()
  124.         read_count = Signal(6)
  125.         self.sync += \
  126.             If(read_clr,
  127.                 read_count.eq(0)
  128.             ).Elif(read_inc,
  129.                 read_count.eq(read_count + 1)
  130.             )
  131.  
  132.  
  133.         # Divider
  134.         # Here is the code for the dividing the input values with the quantization values.
  135.  
  136.         # Intialising variables.
  137.         data_temp_signed = Signal(12,1)
  138.         data_temp_unsigned = Signal(12)
  139.         mult_temp_unsigned = Signal(29)
  140.         mult_temp_unsigned_original = Signal(12)
  141.         mult_temp_signed_original = Signal(12)
  142.         mult_temp_unsigned_round = Signal(12)
  143.         sign = Signal(1)
  144.  
  145.  
  146.         self.comb += [
  147.             # Take an input and store it in data_temp_signed along with the sign.
  148.             # Sign because we obtain floating point value after the division
  149.             # process, hence the sign will help in rounding off to the nearest
  150.             # neighbour.
  151.             data_temp_signed.eq(data_mem[read_count]),
  152.  
  153.             # Getting wheather it is a positive or negative integer.
  154.             # sign = 1 (for negative).
  155.             # sign = 0 (for positive).
  156.             sign.eq(data_temp_signed[11]),
  157.  
  158.             # Making the Input unsigned from signed.
  159.             # If positive :
  160.             # than sign == 0 , data_temp_unsigned = data_temp_signed
  161.             # Else if negative :
  162.             # than sign == 1 , data_temp_unsigned = data_temp_singed*(-1)
  163.             data_temp_unsigned.eq(data_temp_signed + (-2*sign*data_temp_signed)),
  164.  
  165.             # Doing division with the quantization values.
  166.             mult_temp_unsigned.eq(data_temp_unsigned*inverse[read_count]),
  167.  
  168.             # Dividing by (2**16) intially multiplied.
  169.             mult_temp_unsigned_original.eq(mult_temp_unsigned[16:28]),
  170.  
  171.             # Rounding the value of the output get.
  172.             mult_temp_unsigned_round.eq(mult_temp_unsigned_original+(mult_temp_unsigned[15])),
  173.  
  174.             # Putting the sign back.
  175.             mult_temp_signed_original.eq(mult_temp_unsigned_round + (-2*sign*mult_temp_unsigned_round)),
  176.  
  177.             # Making it at the output.
  178.             source.data.eq(mult_temp_signed_original)
  179.         ]
  180.  
  181.         self.sync += [
  182.           If(block_inc,
  183.                block_count.eq(block_count + 1))
  184.         ]
  185.  
  186.  
  187.         self.submodules.read_fsm = read_fsm = FSM(reset_state="IDLE")
  188.         read_fsm.act("IDLE",
  189.             read_clr.eq(1),
  190.             If(read_sel == write_sel,
  191.                 read_swap.eq(1),
  192.                 NextState("READ")
  193.             )
  194.         )
  195.         read_fsm.act("READ",
  196.             source.valid.eq(1),
  197.             source.last.eq(block_count == 63),
  198.             block_inc.eq(read_count == 63),
  199.             #source.last.eq(read_count == 63),
  200.             If(source.ready,
  201.                 read_inc.eq(1),
  202.                 If(source.last,
  203.                     NextState("IDLE")
  204.                 )
  205.             )
  206.         )
Add Comment
Please, Sign In to add comment