In reply to gowthami:
The short answer is "generate more stimulus"
Most simulators support code coverage and they will report which lines of code have not been hit' or exercised. You can run multiple tests and merge the coverage from each one to see the aggregated totals.
Assuming your design comprises several blocks/modules. Once you stitch those blocks together in your system many of the IP blocks are internal i.e. their ports are no longer accessible to the outside world. This can make it hard to get high code coverage, especially for the metrics such as expression and condition coverage. One thing you can do is run block level testbenches for each of the IP blocks. Since these testbenches have access to all of the IP ports, then you can achieve higher block level coverage. You save the coverage data from each of the block level testbenches.
You can merge the block level coverage with the coverage from your top level / system level simulation so that you get the credit for the block level coverage results. It may require some pre-processing of the block level coverage information before you can merge it with the system level coverage, but it can be done.